首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在多个键中的一个上退出缓存

在多个键中的一个上退出缓存
EN

Stack Overflow用户
提问于 2016-12-06 10:04:22
回答 2查看 15K关注 0票数 8

在我的应用程序中,我有多个具有多个键的可缓存方法:

代码语言:javascript
复制
@Cacheable(cacheNames = "valueCodes", key = "{#value, #fieldId, #projectId}")
@Cacheable(cacheNames = "fieldNames", key = "{#field, #value, #projectId}")
@Cacheable(cacheNames = "qi", key = "{#langCode, #question, #projectId}")
@Cacheable(cacheNames = "fieldCodes", key = "{#name, #projectId}")

现在,我需要一个cachevict方法,它清除所有缓存,其中 #projectId键,它是UUID,匹配:

代码语言:javascript
复制
@CacheEvict(value = {"valueCodes", "fieldCodes", "qi"; "fieldCodes"}, key = "#projectId")

我在的文章中看到这是不可能的,而且

每个cacheNames中只有退出注释的键正则表达式匹配多个元素

我不太清楚这是什么意思,但我想这与在SpEL中使用regex有关。

所以我开始考虑把我的钥匙连接成一个键:

代码语言:javascript
复制
@Cacheable(cacheNames="cahceName", key="concat(#projectId).concat(#otherKey)")

并使用regex将所有键与projectId匹配,后面是通配符。但我真的想不出办法来。

我想要达到的目标是可能的吗?如果是的话,我该怎么做?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-09 09:54:19

我没有使用注释来通过部分键查找密钥,而是创建了一个bean来管理密钥

  1. 我删除了所有@CacheEvict注释。
  2. 创建了一个新服务来管理所有缓存的驱逐 公共接口CacheEvictionService { /** *将提供的密钥添加到一个全局密钥列表中,这些键是我们以后需要的,用于驱逐** @param键,用于任何条目*/ void addKeyToList(字符串键)的缓存密钥;/** *查找包含部分键** @param partialKey的键,即匹配密钥*/ list findKeyByPartialKey(String PartialKey)的条目*@返回列表的缓存部分密钥;/** *为匹配所提供的键** @param键的条目配置缓存和密钥--您想要删除*/ void退出项的键(字符串键);} @Service公共类CacheEvictionServiceImpl实现CacheEvictionService { LinkedHashSet cachedKeys =新的LinkedHashSet<>();@Override void addKeyToList(String key) { this.cachedKeys.add( key );}@覆盖公共列表findKeyByPartialKey(String partialKey) { List foundKeys =新的ArrayList<>();for (String cachedKey : this.cachedKeys) { if (cachedKey.contains(partialKey)) { foundKeys.add(cachedKey);}返回foundKeys;}@重载@CacheEvict(值= {"valueCodes“、"fieldCodes”、"qi“、"fieldNames”、"fieldsByType"}、key = "#key")公开无效退出(字符串键){this.cachedKeys.remove(键);}}
  3. 不要使用多个键,而是将不同的键连接到一个字符串中。 @Cacheable(cacheNames = "valueCodes",key = "#value.concat(#fieldId).concat(#projectId)")
  4. 每次缓存时发送到服务的密钥。 ( cacheEvictionService.addKeyToList(StringUtils.join(value,fieldId,projectId);
  5. 循环遍历包含项目id (或任何其他键)的现有密钥。 for (字符串cachedKey :cachedKey{ cacheEvictionService.evict(cachedKey);}
票数 3
EN

Stack Overflow用户

发布于 2016-12-06 16:42:04

我想要达到的目标是可能的吗?如果是的话,我该怎么做?

你喜欢做的事是不可能的。

一般来说,缓存的作用就像哈希表,您只能对唯一的键进行操作。选择属于项目id的所有内容将需要缓存中的索引和查询机制。有些缓存有这种功能,但不是全部,并且没有通用的标准来实现这一点。

再次检查是否真正有意义的缓存所有的零碎,属于一个项目的单独。如果所有的东西都需要一起驱逐的话,也许它一直都在一起使用。或者,例如,将ConcurrentHashMap作为值保存在缓存中,该缓存保存属于项目的各种组件。

有关此问题的更多信息,请参见问题:对于多级别的进程内缓存,有什么更好的选择?

可能删除注释并直接使用缓存是有意义的。带有注释的选项是有限的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40992604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档