大家在做JAVA WEB项目的时候一些常用的属性都是怎么处理的?例如:一个用户表作为主表,用户类型表为其附表,用户类型会很频繁的用到,但用户类型表中的数据量不会太多,大家一般的解决办法是怎样的?
是每次要显示类型的时候根据用户表中跟用户类型关联的ID在用户类型表中取值么?
我觉得这样做的话数据库压力大
我现在的做法是
写一个过滤器,在init(FilterConfig filterConfig)方法中加载如用户类型,用户状态等表数据到ServletContext中,在页面上要用到的时候直接用EL取值
这种做法就是占内存
大家有没有更好的解决办法?

解决方案 »

  1.   

    可以放到session中。如果不是太大的话!
      

  2.   

    一般类型比较固定,可以写个配置文件在启动时自动加载到session中需要的时候直接取,这时候就不用访问数据库了,而且只要写一次通用的很方便
      

  3.   


    我的加载策略就是在项目启动加载,有变化的时候在action中把context中的数据更新为什么用枚举?
    我用的是arraylist中存放javabean的方式...
      

  4.   

    放session是什么意思?
    在过滤器的init(FilterConfig filterConfig)中有session么?
    还是每来一个加载一次数据?
    那个没意义了。。
      

  5.   


    这样不行吧 我要修改了用户类型 启不要重启服务我感觉应该每次用到的时候读库 这样才能保证 实时性
    (能保证session在数据库内容修改时同时更新吗?)
      

  6.   

    把所有用户的都放Application里面,反正数据不多。。
      

  7.   

    这种东西放 servlet context 里面就行了。才几条数据啊。
      

  8.   

    我是自己写了个小的缓存,每隔指定的时间后,若有请求来临,则刷新缓存,代码如下,仅供参考:/**
     * <p>System.Config 配置缓存</p>
     *
     * @author frankiegao123
     * 2010-6-10 下午02:48:35
     */
    public class ConfigCache implements ConfigService {    private final static Log log = Logger.getLog(ConfigCache.class);    /**
         * 最大缓存超时时间(缓存超过此时间时,需要重新刷新缓存)
         */
        private final static long TIMEOUT = ConfigurationHelper.getInt("cache.timeout") * 60L * 1000L;    /**
         * 更新缓存时记录的时间
         */
        private volatile long time = 0L;    /**
         * 正在更新缓存时的门闩,为 true 时表示当前没有更新缓存,为 true 时表示当前正在更新缓存
         */
        private volatile boolean updateGate = true;    /**
         * 缓存容器
         */
        private Map<String, SysConfig> cache = new ConcurrentHashMap<String, SysConfig>();    private CommonDao commonDao;    public ConfigCache(CommonDao commonDao) {
            this.commonDao = commonDao;
            log.info("initializing cache...");
            // 初始化时立即填充缓存
            refreshCache();
            time = System.currentTimeMillis();
            log.info("initialized cache finished, cache size: {0}, set cache time to current: {1}, cache timeout: {2}ms", cache.size(), String.valueOf(time), String.valueOf(TIMEOUT));
        }    /**
         * <p>根据配置的键名获取配置值</p>
         *
         * @param configKey
         * @return
         * @author frankiegao123
         * 2010-6-10 上午11:18:33
         */
        public SysConfig getSysConfig(String configKey) {
            long current = System.currentTimeMillis();
            
            // 当前有线程进行更新时,其他线程继续读取旧的数据
            if(updateGate && isTimeout(current)) {
                synchronized (this) {
                    if(updateGate) {
                        timeoutSynRefresh(current);
                    }
                }
            }
            return cache.get(configKey);
        }    /**
         * <p>超时时更新缓存。该方法需要在同步环境中调用</p>
         * @param current
         * @author frankiegao123
         * 2010-6-10 上午11:16:30
         */
        private void timeoutSynRefresh(long current) {
            updateGate = false;
            log.info("refresh cache start..., time out: {0,number,0.00}, size: {1}, set updateGate to false", (current - time) / 1000.0, cache.size());
            try {
                refreshCache();
                time = current;
                log.info("refresh cache finished, size after update: {0}, set cache time to current: {1}", cache.size(), String.valueOf(time));
            } catch (Exception e) {
                log.error("refresh cache failed", e);
            } finally {
                updateGate = true;
                log.info("refresh cache finished, set updateGate to true");
            }
        }    /**
         * <p>更新缓存数据</p>
         *
         * @author frankiegao123
         * 2010-6-10 上午11:15:55
         */
        private void refreshCache() {
            List<SysConfig> configs = commonDao.getSysConfigs();
            for(Iterator<SysConfig> i = configs.iterator(); i.hasNext(); ) {
                SysConfig config = i.next();
                cache.put(config.getConfigKey(), config);
            }        // 清除 JPA persistence contenxt 缓存
            commonDao.clear();        // 每次刷新后输出测试 KEY 的值,以便于检查刷新是否正确
            SysConfig config = cache.get(SysConfig.TEST_KEY);
            if(config == null) {
                log.error("refresh cache, cannot find TEST_KEY");
            } else {
                log.info("refresh cache, find TEST_KEY = [{0}]", config.getConfigValue());
            }
        }    /**
         * <p>缓存是否超时</p>
         *
         * @param current
         * @return
         * @author frankiegao123
         * 2010-6-10 上午11:16:12
         */
        private boolean isTimeout(long current) {
            return (current - time >= TIMEOUT);
        }    // 以下方法在监控页面显示缓存,并管理之用
        Collection<SysConfig> getSysConfigs() {
            return Collections.unmodifiableCollection(cache.values());
        }    int getSize() {
            return cache.size();
        }    long getTime() {
            return time;
        }    boolean isUpdateGate() {
            return updateGate;
        }    void refresh() {
            time = 0L;
            log.info("refresh: reset cache time to 0");
            getSysConfig("none");
            log.info("refresh: refresh cache finished, cache: {0}", String.valueOf(time));
        }
    }
      

  9.   

    我感觉没有必要存哈,直接一条sql表关联就好了,查询也是一条sql,加个关联也不会影响效率的
      

  10.   

    谢谢大家的宝贵意见我仔细看过了各位的意见,我觉得像类型,状态等这种数据量比较少的时候存到servlet context里面还是比较好的做法,在这些属性变化,如添加类型时在action的addtype时把servletcontext中的内容取出来,然后添加新的状态,然后再更新数据库。dickli1986说的SQL关联的话,我觉得不太好每一的访问都需要创建数据库连接,只查一张表的数据肯定要比SQL关联的效率高,而且数据库压力要小期望更高手的回答
      

  11.   

    赞一个...
    频繁的数据一定要放到缓存里面去,你只要定时更新缓存就行了,如果有兴趣你可以去 起点 网站看看他们月票刷新..绝对用的缓存...java的分布式缓存有 memcache 还有其他的比如oscache
      

  12.   


    肯定会知道啊,不如说用户类型,当你添加、删除用户类型的时候不就有变化么?在添加、删除的方法需要改变ServletContext里面的值