根据试题ID从缓存查询的时候,为了防止缓存穿透,会将不存在的试题查询ID,放到Redis缓存起来。项目实例:

    1. List<String>cacheKeys=new ArrayList<>();
    2. List<String>notExistValidateKey=new ArrayList<>();
    3. for(String queId:queIds){
    4. // 正常的缓存
    5. cacheKeys.add(RedisConstants.QUESTION_RELATION_CACHE_KEY+queId);
    6. // 不存在的试题id,防止缓存穿透
    7. notExistValidateKey.add(RedisConstants.NOT_EXIST_QUESTION_CACHE_KEY+queId);
    8. }
    9. // 从缓存中查询出不存在的试题
    10. List<String>notExistQueIds=redisService.batchGetObject(notExistValidateKey,String.class);
    11. if(CollectionUtils.isNotEmpty(notExistQueIds)){
    12. // 正常试题ID集合中把这些不存在的过滤掉
    13. queIds.removeAll(notExistQueIds);
    14. cacheKeys.removeAll(getNotExistKeysByNotExistQueIds(notExistQueIds));
    15. if(CollectionUtils.isEmpty(queIds)){
    16. return null;
    17. }
    18. }
    19. // ....
    20. // 保存不存在的试题
    21. saveNotExistRelation(queIds,relations);
    1. /**
    2. * @description: 保存不存在的试题
    3. */
    4. private void saveNotExistRelation(List<String>queIds,List<QuestionSplitRelation>existRelation){
    5. if(new HashSet<>(queIds).size() <= existRelation.size()){
    6. return;
    7. }
    8. List<String>notExistQueIds=new ArrayList<>();
    9. if(CollectionUtils.isEmpty(existRelation)){
    10. notExistQueIds.addAll(queIds);
    11. }else{
    12. notExistQueIds=(List)CollectionUtils.subtract(queIds,ListUtils.fetchFieldValue(existRelation,"queId"));
    13. }
    14. Map<String,Object>caches=new HashMap<>();
    15. for(String rel:notExistQueIds){
    16. caches.put(RedisConstants.NOT_EXIST_QUESTION_CACHE_KEY+rel,rel);
    17. }
    18. // 目前缓存仅保存10秒,后期加入 binlog 同步则可适当增加时间
    19. redisService.batchSetObject(caches,10);
    20. }