Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将缓存与不同字段/键上的查询一起使用?_Java_Spring_Caching_Ehcache_Evict - Fatal编程技术网

Java 如何将缓存与不同字段/键上的查询一起使用?

Java 如何将缓存与不同字段/键上的查询一起使用?,java,spring,caching,ehcache,evict,Java,Spring,Caching,Ehcache,Evict,我正在实现一个基于SpringMVC的web应用程序,我在其中添加了缓存,但现在面临一个问题,即当更改应用于底层数据库时,如何操作缓存 我一直在研究Ehcache提供的文档,但没有找到任何好的例子来解决我的问题 假设我有一个DAO类,我选择在两个方法上应用缓存,这两个方法返回一个对象列表—不可编译的伪代码: @Repository public class MyEntityDao { @Autowired DataSource ds; @Autowired EhCac

我正在实现一个基于SpringMVC的web应用程序,我在其中添加了缓存,但现在面临一个问题,即当更改应用于底层数据库时,如何操作缓存

我一直在研究Ehcache提供的文档,但没有找到任何好的例子来解决我的问题

假设我有一个DAO类,我选择在两个方法上应用缓存,这两个方法返回一个对象列表—不可编译的伪代码:

@Repository
public class MyEntityDao {

   @Autowired
   DataSource ds;

   @Autowired
   EhCacheCacheManager cacheManager;

   @Autowired
   CacheKeyGenerator keyGenerator;

   @Cacheable("myEntityCache")
   public List<MyEntity> findByFieldAlpha(String fieldAlpha) {
       return ds.query("select * from MyEntity where fieldAlpha = #fieldAlpha").execute();
   }

   @Cacheable("myEntityCache")
   public List<MyEntity> findByFieldBeta(String fieldBeta) {
       return ds.query("select * from MyEntity where fieldBeta = #fieldBeta").execute();
   }

   public void deleteByFieldAlpha(String fieldAlpha) {
      ds.query("delete from MyEntity where fieldAlpha = #fieldAlpha").execute();
   }

   public void deleteByFieldBeta(String fieldBeta) {
      ds.query("delete from MyEntity where fieldBeta = #fieldBeta").execute();
   }

   public void store(MyEntity myEntity) {
      ds.insert(myEntity).execute();
   }
}
我需要解决的一个明显的问题是,在向基础数据库添加或删除数据时,应该如何实现缓存修改策略

对于store方法,我发现要解决的问题非常简单:

 ...

 public void store(MyEntity myEntity) {
    boolean success = ds.insert(myEntity).execute();
    if (success) {
       Cache cache = cacheManager.getCache("myEntityCache")

       String keyFieldAlpha = keyGenerator.generateCacheKey("findByFieldAlpha", myEntity.getFieldAlpha());
       List cacheListFieldAlpha = (List) cache.get(keyFieldAlpha).getObjectValue();
       cacheListFieldAlpha.add(myEntity);

       String keyFieldBeta = keyGenerator.generateCacheKey("findByFieldBeta", myEntity.getFieldBeta());
       List cacheListFieldBeta = (List) cache.get(keyFieldBeta).getObjectValue();
       cacheListFieldBeta.add(myEntity);
    }
 }
但是对于delete方法,事情变得复杂得多

到目前为止,这是我提出的一个实现,但它似乎比应该的要复杂得多。如果我的设计模式是正确的,或者应该以任何其他方式解决我的问题,有人有任何有价值的意见吗

public void deleteByFieldAlpha(String fieldAlpha) {
  List<MyEntity> myEntititesToBeDeleted = this.findByFieldAlpha(fieldAlpha);
  boolean success = ds.query("delete from MyEntity where fieldAlpha = #fieldAlpha").execute();
  if (success) {
     Cache cache = cacheManager.getCache("myEntityCache")

     String keyFieldAlpha = keyGenerator.generateCacheKey("findByFieldAlpha", fieldAlpha);
     cache.remove(keyFieldAlpha);

     for (MyEntity myEntity : myEntititesToBeDeleted) {
        String keyFieldBeta = keyGenerator.generateCacheKey("findByFieldBeta", myEntity.getFieldBeta());
        List cacheListFieldBeta = (List) cache.get(keyFieldBeta).getObjectValue();
        cacheListFieldBeta.remove(myEntity); 
     }
  }
}

也许这是解决问题的正确方法?我没有偶然发现任何解决这些问题的方法,所以我在这里给出了我最好的猜测。

我会给你我的意见。这似乎几乎是正确的解释。我认为删除操作之后,应该清空所有缓存并重新启动。通常,在数据更改操作后,缓存会重置。这是因为表连接。这似乎不是你的情况,因为你只有两个查询,没有连接,但通常缓存会被清理并重新启动。这样做,在fieldAlfa发生更改后,您不需要扫描指向fieldBeta的缓存。希望这能对你有所帮助。
顺便说一句,MyBatis就是这样工作的。

使用Ehcache,可能在您的情况下,操作员会很有用。

请详细说明这将如何解决我的问题。
public void deleteByFieldAlpha(String fieldAlpha) {
  List<MyEntity> myEntititesToBeDeleted = this.findByFieldAlpha(fieldAlpha);
  boolean success = ds.query("delete from MyEntity where fieldAlpha = #fieldAlpha").execute();
  if (success) {
     Cache cache = cacheManager.getCache("myEntityCache")

     String keyFieldAlpha = keyGenerator.generateCacheKey("findByFieldAlpha", fieldAlpha);
     cache.remove(keyFieldAlpha);

     for (MyEntity myEntity : myEntititesToBeDeleted) {
        String keyFieldBeta = keyGenerator.generateCacheKey("findByFieldBeta", myEntity.getFieldBeta());
        List cacheListFieldBeta = (List) cache.get(keyFieldBeta).getObjectValue();
        cacheListFieldBeta.remove(myEntity); 
     }
  }
}