美文网首页
缓存系统

缓存系统

作者: 榷奕 | 来源:发表于2019-10-13 16:33 被阅读0次

    2020.3.11追加
    如果有多个缓存需要CacheManager

    1. 缓存系统设计逻辑

    按照数据表来分,一个数据表一个Mapper一个Service(除非巨傻逼的表设计有问题才一个Mapper放多个表)。

    如果涉及到多张表的话,非要是用缓存,那就再封一个Service,然后调用刚才只有一张表的那个低层Service。

    低层Service的方法,基本也就是表增删改,然后在相应的方法上面,打上那三个注解,这样这个表一变,肯定缓存也就跟着更新了。

    2. 注解

    @Service
    public class DemoServiceImpl implements DemoService {
        @Autowired
        PersonRepository personRepository;
        
        @Cacheable(value = "people", key = "#person.id")
        @Override
        public Person findOne(Person person) {
            Person p = personRepository.findOne(person.getId());
            System.out.println("为id、key为" + p.getId() + "数据做了缓存");
            return p;
        }  
        @CacheEvict(value = "people")
        @Override
        public void remove(Long id) {
            System.out.println("删除了id、key为" + id + "的数据缓存");
            personRepository.delete(id);
        }
        @CachePut(value = "people", key = "#person.id")
        @Override
        public Person save(Person person) {
            Person p = personRepository.save(person);
            System.out.println("为id、key为" + p.getId() + "数据做了缓存");
            return p;
        }
    }
    
    img

    注解里面的value就是缓存名字

    3. @CacheConfig

    所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,所以,有了@CacheConfig这个配置。

    @CacheConfig(cacheNames = {"myCache"})
    public class BotRelationServiceImpl implements BotRelationService {
    
        @Cacheable(key = "targetClass + methodName +#p0")
        public List<BotRelation> findAllLimit(int num) {
            return botRelationRepository.findAllLimit(num);
        }
    
    }
    

    4. key生成策略

    看到下面的这个key生成策略,基本上key一定要自己指定了。

    如果自己写了key是多少的话,就按照写的来;如果没写的话,这个自动生成,大概流程是,method名+字段名+字段值,封成一个Map,然后再转成Json,再做Md5加密。

    (如果生成的话,基本不可能再人为操纵它了)

    public class CacheKeyGenerator implements KeyGenerator {
        @Override
        public Object generate(Object target, Method method, Object... params) {
            
            //  关键点也就这三行!!!
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("target", target.getClass().toGenericString());//放入target的名字
            map.put("method", method.getName());//放入method的名字
            
            if (params != null && params.length > 0) {//把所有参数放进去
                int i = 0;
                for (Object o : params) {
                    map.put("params-" + i, o);
                    i++;
                }
            }
            String str = JSONObject.toJSON(map).toString();
            byte[] hash = null;
            String s = null;
            try {
                hash = MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8"));
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            s=MD5Encoder.encode(hash);//使用MD5生成位移key
            return s;
        }
    }
    

    5. 如果没有按照每张表一个服务这种设计

    如果没有按照每张表一个服务这种设计,那么就很难用注解来写了,至少我目前没想到怎么用注解。不过这种情况下可以自己注册RedisService,里面封好get / set / delete方法,然后自己手动缓存啊。(这种情况比较复杂,因为如果一旦涉及到多张表,变数可能就比较大)

    再分两种情况吧:

    1. 一张表对应了好几个功能
      那就把这好几个功能一起来做缓存
    2. 好几张表对应了好几个功能
      这种情况下要不咱们就别缓存了。。。就是只要这个功能对应了好几张表,几张表还变,那要不别考虑了。。。

    相关文章

      网友评论

          本文标题:缓存系统

          本文链接:https://www.haomeiwen.com/subject/wmfkmctx.html