大家在做JAVA WEB项目的时候一些常用的属性都是怎么处理的?例如:一个用户表作为主表,用户类型表为其附表,用户类型会很频繁的用到,但用户类型表中的数据量不会太多,大家一般的解决办法是怎样的?
是每次要显示类型的时候根据用户表中跟用户类型关联的ID在用户类型表中取值么?
我觉得这样做的话数据库压力大
我现在的做法是
写一个过滤器,在init(FilterConfig filterConfig)方法中加载如用户类型,用户状态等表数据到ServletContext中,在页面上要用到的时候直接用EL取值
这种做法就是占内存
大家有没有更好的解决办法?
是每次要显示类型的时候根据用户表中跟用户类型关联的ID在用户类型表中取值么?
我觉得这样做的话数据库压力大
我现在的做法是
写一个过滤器,在init(FilterConfig filterConfig)方法中加载如用户类型,用户状态等表数据到ServletContext中,在页面上要用到的时候直接用EL取值
这种做法就是占内存
大家有没有更好的解决办法?
我的加载策略就是在项目启动加载,有变化的时候在action中把context中的数据更新为什么用枚举?
我用的是arraylist中存放javabean的方式...
在过滤器的init(FilterConfig filterConfig)中有session么?
还是每来一个加载一次数据?
那个没意义了。。
这样不行吧 我要修改了用户类型 启不要重启服务我感觉应该每次用到的时候读库 这样才能保证 实时性
(能保证session在数据库内容修改时同时更新吗?)
* <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));
}
}
频繁的数据一定要放到缓存里面去,你只要定时更新缓存就行了,如果有兴趣你可以去 起点 网站看看他们月票刷新..绝对用的缓存...java的分布式缓存有 memcache 还有其他的比如oscache
肯定会知道啊,不如说用户类型,当你添加、删除用户类型的时候不就有变化么?在添加、删除的方法需要改变ServletContext里面的值