Java缓存和动态更新

时间:2012-01-30 18:37:41

标签: java design-patterns caching tomcat servlets

我需要在servlet启动时从数据库“预加载”一些数据。

所以我想创建一些缓存,例如使用HashMap或类似的同步版本。

我还需要更新数据库更新更改的缓存 所以我想添加一些“听众”。

我的问题是:这是以某种方式提供还是我必须实际实现它?

如果是,那么哪种设计模式是最佳方法?

更新
没有使用JPA或ORM。但春天可用

4 个答案:

答案 0 :(得分:3)

是的,你当然可以实现这一点 我将绘制一个小型架构然后向你解释它:

Architecture diagram

首先,您可以了解Mappers here和TDG here。 映射器有一个名为 cacheAll()的方法,它调用并委托给TDG的方法 cacheAll(),该方法的任务是从数据库中获取表中的所有行(要在缓存对象中缓存的行)。

所以首先你要创建一个实现“ServletContextListener”的监听器 这意味着它是整个servlet上下文的监听器,并且在其 contextInitialized 中你必须调用 mp.fill(Mapper.cacheAll()),所以它就像(这是通用代码,当然写得更好并优化它)

public class myServletContextListener implements ServletContextListener{

@Override
public void contextInitialized(ServletContextEvent sce) {
        mp.fill(Mapper.cacheAll());
 }

//
}

不要忘记在web.xml中添加你的监听器:

<listener>
    <listener-class>myServletContextListener </listener-class>
</listener>

所以这将做什么,是在服务器启动时,将所有记录缓存到缓存对象中的hashmap mp。

至于根据数据库更改更新缓存,您必须使用observer pattern

更新
我忘了提及,关于缓存对象,我假设您希望所有用户或您的应用都可以访问它,因此您应该将其编码为单例(单例模式),代码如下:

 public class cacheObject
{
    private static Map cMap;
    private static cacheObject cObject;
    private cacheObject()
    {
        cMap = Mapper.cacheAll();
    }
    public static synchronized cacheObject getInstance()
    {
        if (cObject == null){
            cObject = new cacheObject();
        }
        return cObject;
    }

}

此外,如果您要缓存的数据可以由用户更改,那么请将其设为 Threadlocal 单例。

答案 1 :(得分:2)

您可以在Guava点找到最符合您需求的服务。 Caches上的wiki article可能与您最相关,但这里的确切方法在很大程度上取决于数据库更新更改的条件。如果要刷新数据库更新更改的整个缓存 - 或者至少使旧条目无效 - 只要发生数据库更新,您就可以调用Cache.invalidateAll()。如果您愿意让缓存略微落后于时间,那么使用CacheBuilder.refreshAfterWrite(long, TimeUnit)可能会对您有效。

答案 2 :(得分:0)

Hashmap和它的线程安全变体ConcurrentHashMap已经可用。

有一些缓存解决方案可以像ehcache一样提供,它也提供了诸如驱逐策略等高级支持。

关于设计模式,请阅读Observer设计模式。

答案 3 :(得分:0)

我实际上有一个生产水平项目,我需要做这样的事情。我的解决方案是(这只是我的解决方案)是在servlet启动时将对象(你的“数据”)加载到内存中。做出这个决定是因为该对象足够大,使得客户端请求缓慢从数据库中提取并且我有少量并发用户。任何会在数据库中更改该对象数据的请求也会更改内存中的对象。如果您正在与许多用户合作,您当然需要使用同步对象来执行此操作。如果数据量不是很大,那么每次用户请求有关数据的信息时,您都可以随时从数据库中提取数据。

祝你好运。