我有一个Spring应用程序,它使用MyBatis实现持久性。我使用ehcache,因为速度对这个应用程序很重要。我已经设置并配置了MyBatis和Ehcache。我使用一个名为"mybatis“的缓存,因为否则,为每个实体创建单独的缓存将是荒谬的。
这是我的ehcache.xml。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="false"
monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir" />
<cache name="mybatis"
maxBytesLocalHeap="100M"
maxBytesLocalDisk="1G"
eternal="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="true"
overflowToDisk="true"
memoryStoreEvictionPolicy="LFU">
</cache>
<cache name="jersey"
maxBytesLocalHeap="100M"
maxBytesLocalDisk="1G"
eternal="false"
timeToLiveSeconds="600"
timeToIdleSeconds="300"
statistics="true"
overflowToDisk="true"
memoryStoreEvictionPolicy="LFU">
</cache>
</ehcache>这里是我的mapper界面的一个示例。
import java.util.List;
public interface InstitutionMapper {
@Cacheable(value = "mybatis")
List<Institution> getAll();
@Cacheable(value = "mybatis", key = "id")
Institution getById(long id);
@CacheEvict(value = "mybatis")
void save(Institution institution);
@CacheEvict(value = "mybatis", key = "id")
void delete(long id);
}因为我有一个共享缓存,所以我需要一种使我的密钥成为域对象唯一的方法。例如,在保存或删除时,我需要清除缓存,以便新值将显示在UI中。但是,我不想清除整个缓存。我不知道如何处理这个问题,以便当delete被调用并且缓存被逐出时,只有在带有ID的执行机构的mybatis中的条目才被清除。
密钥需要类似于域名+ params。以机构+ id为例。希望这是合理的。
我看到了这篇文章,但它似乎是以类名+方法+ params的方式进行的。
发布于 2015-07-28 12:55:43
为整个域模型设置一个区域是有点奇怪的(至少可以这么说)。我可以想象,您可以在同一个缓存中收集具有相似语义的对象类型,但不是所有对象类型。你在这里提出的大多数问题,如果你有适当的分界,就会自行解决。
但为了解释起见,这里有一些想法。
你的getAll()需要一个密钥。如果您不提供一个,那么基本上任何没有参数的其他@Cacheable方法都会与缓存中的相同键发生冲突。
@Cacheable(value = 'mybatis', key = "'institutions'")
List<Institution> getAll();您的@CacheEvict不会清除缓存的列表(从getAll()方法中),因此您可能会在一种情况下驱逐某个机构,而它仍然显示在缓存的getAll()调用中。如果要在多个级别缓存相同的内容,最好在更新/删除某个内容时删除整个区域。当然,如果每个实体类型都有一个区域,那么这就不是什么问题了。
您的save方法没有id。它到底要驱逐什么?它怎么知道它必须通过id找到一个现有的机构?
@CacheEvict(value = "mybatis", key = "#p0.id")
void save(Institution institution);(但这并不能解决getAll()的不一致性问题)
您的getById不需要密钥,因为您拥有的唯一方法参数是,是id的。回到你最初的“问题”,如果你想在你的钥匙前加上一些东西,你需要全面地去做(这样驱逐就可以用同样的键了)。我不会在SpEL上这么做,因为有机会忘记一个案子太高了。
您可以实现自定义的KeyResolver,并根据方法的返回类型追加唯一的前缀。
话虽如此,但您的示例代码几乎是错误的,所以我建议您检查一下有关此主题的文档
https://stackoverflow.com/questions/31661986
复制相似问题