缓存笔记二(代码实践)

2 缓存在 java 中的实现

在 Java 中,我们一般对调用方法进行缓存控制,比如我调用"findUserById(Long id)", 那么我应该在调用这个方法之前先从缓存中查找有没有,如果没有再掉该方法如从数据 库加载用户,然后添加到缓存中,下次调用时将会从缓存中获取到数据。Java 中广泛使 用的分布式缓存 Redis

2.1 缓存逻辑流程

流程图如下:

2.2 逻辑流程代码:

@Override
    public Provinces detail(String provinceid) {
        Provinces provinces = null;


        //在redis查询
        provinces = (Provinces)redisTemplate.opsForValue().get(provinceid);
        if (null != provinces){
//            redisTemplate.expire(provinceid,20000, TimeUnit.MILLISECONDS);
            System.out.println("缓存中得到数据");
            return provinces;
        }


        provinces = super.detail(provinceid);
        if (null != provinces){
            redisTemplate.opsForValue().set(provinceid,provinces);//set缓存
            redisTemplate.expire(provinceid,2000000, TimeUnit.MILLISECONDS);//设置过期
        }


        return provinces;
    }


3 基于注解的 Cache

Spring 3.1 起,提供了基于注解的对 Cache 的支持。使用 Spring Cache 的好处: 基于注解,代码清爽简洁;

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {




    //key的生成,springcache的内容,跟具体实现缓存器无关
    //自定义本项目内的key的方式
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {


                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getSimpleName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }


    //不支持过期时间
//    @Bean
//    public CacheManager cacheManager() {
//        //jdk里,内存管理器
//        SimpleCacheManager cacheManager = new SimpleCacheManager();
//        cacheManager.setCaches(Collections.singletonList(new ConcurrentMapCache("province")));
//        return cacheManager;
//    }


    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        return RedisCacheManager
                .builder(connectionFactory)
                .cacheDefaults(
                        RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofSeconds(200))) //缓存时间绝对过期时间20s
                .transactionAware()
                .build();
    }


    /**
     * 序列化object对象为json字符串
     */
//    @Bean
//    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
//        RedisTemplate<String, Object> template = new RedisTemplate<>();
//        template.setConnectionFactory(factory);
//
//        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
//        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
//        ObjectMapper mapper = new ObjectMapper();
//        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        serializer.setObjectMapper(mapper);
//        template.setValueSerializer(serializer);
//
//        //使用StringRedisSerializer来序列化和反序列化redis的key值
//        template.setKeySerializer(new StringRedisSerializer());
//        template.afterPropertiesSet();
//        return template;
//    }


    /**
     * JdkSerializationRedisSerializer: 序列化java对象(被序列化的对象必须实现Serializable接口),无法转义成对象
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);


        //使用jdk的序列化
        template.setValueSerializer(new JdkSerializationRedisSerializer());
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}
//@Service("provincesService")
@CacheConfig(cacheNames="province") //通用配置
public class ProvincesServiceImpl2 extends ProvincesServiceImpl implements ProvincesService{
//    @Cacheable(value = "province",
//            key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#provinceid")
    @Cacheable// value指定当前接口,要使用哪一个缓存器 --- 如果该缓存器不存在,则创建一个
    public Provinces detail(String provinceid) {//一个接口方法,对应一个缓存器
        return super.detail(provinceid);
    }


    //这个AOP,是先删缓存,先改数据库?
    @CachePut(key = "#entity.provinceid")
    public Provinces update(Provinces entity) {
        return super.update(entity);
    }


    @CacheEvict
    public void delete(String provinceid) {
        super.delete(provinceid);
    }


    //组合配置
    @Caching(put = {
            @CachePut(key = "#entity.provinceid"),
            @CachePut(key = "#entity.provinceid")}
    )
    public Provinces add(Provinces entity) {
        return super.add(entity);
    }


}

接下来将推送几篇有关事务的文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值