zoukankan      html  css  js  c++  java
  • springboot 2 集成 redis 缓存 序列化

    springboot 缓存

    为了实现是在数据中查询数据还是在缓存中查询数据,在application.yml 中将mybatis 对应的mapper 包日志设置为debug 。

    spring:
      datasource:
        username: root
        password: rootpassword
        url: jdbc:mysql://localhost:3306/springboot
        driver-class-name: com.mysql.jdbc.Driver
    debug: true
    logging:
      level:
        com:
          springbootmybatis:
             mapper: debug

    然后在springboot的主类上添加 @EnableCaching 启动缓存。

    然后在service 类中的方法上添加上缓存注解。

    @Cacheable(value = "user")
    public User selectUserById(Integer id) {
        User user = userMapper.selectUserById(id);
        return user;
    }

    @Cacheable

    默认的是将传入参数(id)作为缓存的 key ,方法的返回值作为 value 存入缓存中 。

    在方法 selectUserById(Integer id ) 执行之前 先去根据 key 去缓存中查询是否有该 key 的数据,如果有,则直接在缓存中查询数据,然后返回,不再执行 selectUserById 方法,如果没有在缓存中查到该 key 的数据,才回去执行 selectUserById 方法。

    @CachePut

    @CachePut(value = "user")
    public User updateUser(User user) {
        userMapper.updateUser(user);
        return user;    
    }

    默认的是将传入参数(id)作为缓存的 key ,@CachePut 在方法执行之后执行,将方法返回的结果写入缓存,

    从缓存中查询到的仍然是旧的缓存数据,需要在 @CachePut(value = "user",key = "#result.id") 或者@CachePut(value = "user",key = "#user.id") 只要在 key 设置为 user 的 id ,然后根据id 去查询,就能从缓存中获取修改后的数据。

    @CacheEvict

    @CacheEvict(value = "user",key = "#id")

    清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作 ,可以使用 beforeInvocation 改变删除缓存的时间,当将 beforeInvocation 设置为 true 时,会在执行方法之前删除缓存中指定的元素,不管方法执行是否存在异常,都会删除缓存。 删除指定 key 的缓存。allEntries 默认为 false ,当为 true 时,会忽略指定的 key ,删除所有缓存元素。不指定 key 时默认一方法的参数作为缓存的 key。

    @Caching

    @Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface Caching {
        Cacheable[] cacheable() default {};
        CachePut[] put() default {};
        CacheEvict[] evict() default {};
    }
    @Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
              @CacheEvict(value = "cache3", allEntries = true) })
     public List<User> selectUser() {
            List<User> users = userMapper.selectUser();
            return users;
     }

    使用redis 缓存:

    导入对应的jar:使用fastjson 来序列化value

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>

    在application.yml 添加配置:

    spring: 
        redis: 
             host: #redis 安装的IP,其他的可以不用配置,默认的就可以满足测试需要

    在springboot 1 中配置redis

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.SerializationException;
    
    import java.lang.reflect.Method;
    import java.nio.charset.Charset;
    
    @EnableCaching
    @Configuration
    public class RedisConfig extends CachingConfigurerSupport {
        @Bean
        public KeyGenerator wiselyKeyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
        @Bean
        public CacheManager cacheManager(
                @SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
            return new RedisCacheManager(redisTemplate);
        }
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(
                RedisConnectionFactory factory) {
            StringRedisTemplate template = new StringRedisTemplate(factory);
            FastJsonRedisSerializer<Object> serializer = new FastJsonRedisSerializer<>(Object.class);
            template.setValueSerializer(serializer);
            template.afterPropertiesSet();
            return template;
        }
    
        private static class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
            private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
            private Class<T> clazz;
            public FastJsonRedisSerializer(Class<T> clazz) {
                this.clazz = clazz;
            }
    
            @Override
            public byte[] serialize(T t) throws SerializationException {
                if (t == null) {
                    return new byte[0];
                }
                return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
            }
    
            @Override
            public T deserialize(byte[] bytes) throws SerializationException {
                if (bytes == null || bytes.length <= 0) {
                    return null;
                }
                String str = new String(bytes, DEFAULT_CHARSET);
                return (T) JSON.parseObject(str, clazz);
            }
        }
    }

    然后在测试类上加上缓存的注解就可以在redis中查看已经序列化成json格式的数据。

    在springboot2 中配置redis

    其他的配置不用动,需要修改RedisConfig.java 因为springboot2 中new RedisCacheManager(redisTemplate);被遗弃了

    @Bean
        public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
            //初始化一个RedisCacheWriter
            RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
            //设置CacheManager的值序列化方式为 fastJsonRedisSerializer,但其实RedisCacheConfiguration默认使用StringRedisSerializer序列化key,
            ClassLoader loader = this.getClass().getClassLoader();
    
            FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(loader.getClass());
            RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer);
            RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
            RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
            return cacheManager;
        }

    这样设置就可以正常使用了

     

  • 相关阅读:
    [转]windows下mysql配置文件my.ini的位置
    [转]Oracle 11g不能导出空表的多种解决方法
    [转]ORACLE WITH AS 用法(相当于查询开始前构造临时表,提高效率)
    [转]基于WordPress的微信小程序支付功能开发
    从数据库优化到治病(2)治好心悸过程
    算命三十多年的资深命理师的人生感悟!
    从高维度看世界
    鸾书精华
    实用QPS和TPS高的高效分析方法
    windows 安装 mysql
  • 原文地址:https://www.cnblogs.com/zwb1234/p/9257639.html
Copyright © 2011-2022 走看看