我使用Spring Boot和Spring Cache。我有一个方法,给定一个id列表,返回一个与这些id匹配的Food
列表:
public List<Food> get(List<Integer> ids) {
return "select * from FOOD where FOOD_ID in ids"; // << pseudo-code
}
我想按id缓存结果。想象一下我:
List<Food> foods = get(asList(1, 5, 7));
然后:
List<Food> foods = get(asList(1, 5));
我希望从缓存中检索ID为1的Food
和ID为5的Food
。有可能吗?
我知道我可以做一个像这样的方法:
@Cacheable(key = "id")
public Food getById(id){
...
}
并迭代id列表并每次调用它,但在这种情况下我不会利用IN
SQL运算符,对吧?感谢。
答案 0 :(得分:1)
Cacheable的key属性采用SpEL表达式来计算缓存键。所以你应该能够做类似
的事情@Cacheable(key = "#ids.stream().map(b -> Integer.toString(b)).collect(Collectors.joining(",")))
这将要求id始终处于相同的顺序
更好的选择是创建一个类来包装你能够为你生成缓存键的id,或者某种实用类函数。
没有@Cacheable
的另一种可能的解决方案是将缓存管理器注入类中:
@Autowired
private CacheManager cacheManager;
然后,您可以通过名称
从缓存管理器中检索食物缓存Cache cache = cacheManager.getCache('cache name');
然后你可以调整你的方法以获取id列表并手动添加并从缓存中获取值
cache.get(id);
cache.put(id, food);
您很可能仍然无法使用SQL IN子句,但您至少在方法内处理迭代,而不是在调用此方法的任何地方,并尽可能利用缓存。
public List<Food> get(List<Integer> ids) {
List<Food> result = new ArrayList<>();
for(Integer id : ids) {
// Attempt to fetch from cache
Food food = cache.get(id);
if (food == null) {
// Fetch from DB
cache.put(id, food);
}
result.add(food);
}
return result;
}
相关的Javadocs:
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/CacheManager.html
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/Cache.html