美文网首页
三、SpringBoot 2.x 使用Redis作为项目数据缓存

三、SpringBoot 2.x 使用Redis作为项目数据缓存

作者: maololo | 来源:发表于2018-07-19 10:52 被阅读314次

    一、添加依赖

            <!-- 添加缓存支持 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    
            <!-- 添加Redis缓存支持 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <!-- 工具类 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.15</version>
            </dependency>
    

    二、配置Redis数据库

    spring:
      redis:
        #数据库索引
        database: 1
        host: 192.168.2.230
        port: 6379
        password:
        jedis:
          pool:
            #最大连接数
            max-active: 8
            #最大阻塞等待时间(负数表示没限制)
            max-wait: -1
            #最大空闲
            max-idle: 8
            #最小空闲
            min-idle: 0
        #连接超时时间
        timeout: 10000
    

    三、Redis配置类

    package com.hn.lz.config;
    
    import com.hn.lz.handler.FastJsonRedisSerializer;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.cache.Cache;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.CacheErrorHandler;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    
    import java.lang.reflect.Method;
    import java.time.Duration;
    
    /**
     * Created by mll on 2018/7/16.
     */
    @Configuration
    @EnableCaching  //开启支持缓存
    public class RedisConfiguration extends CachingConfigurerSupport {
    
        static Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);
    
        /**
         * 自定义生成key的规则
         *
         * @return
         */
        @Override
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object o, Method method, Object... objects) {
                    //格式化缓存key字符串
                    StringBuilder sb = new StringBuilder();
                    //追加类名
                    sb.append(o.getClass().getName()).append(".");
                    //追加方法名
                    sb.append(method.getName());
                    //遍历参数并且追加
                    for (Object obj : objects) {
                        sb.append(".");
                        sb.append(obj.toString());
                    }
                    System.out.println("调用Redis缓存Key : " + sb.toString());
                    return sb.toString();
                }
            };
        }
    
        /**
         * 设置 redis 数据默认过期时间
         * 设置 Cache 序列化方式
         *
         * @return
         */
        @Bean
        public RedisCacheConfiguration redisCacheConfiguration() {
            FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
            RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
            configuration = configuration
                    .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer))
                    .entryTtl(Duration.ofDays(30));
            return configuration;
        }
    
    }
    

    四、自定义存入Redis数据库值的序列化方式

    package com.hn.lz.handler;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.SerializationException;
    
    import java.nio.charset.Charset;
    
    /**
     * Created by mll on 2018/7/17.
     */
    public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    
        public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    
        private Class<T> clazz;
    
        public FastJsonRedisSerializer(Class<T> clazz) {
            super();
            this.clazz = clazz;
        }
    
        @Override
        public byte[] serialize(T t) throws SerializationException {
            if (null == t) {
                return new byte[0];
            }
            return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
        }
    
        @Override
        public T deserialize(byte[] bytes) throws SerializationException {
            if (null == bytes || bytes.length <= 0) {
                return null;
            }
            String str = new String(bytes, DEFAULT_CHARSET);
            return (T)JSON.parseObject(str, clazz);
        }
    
    }
    

    五、使用注解来缓存数据

    package com.hn.lz.service;
    
    import com.hn.lz.mapper.UserMapper;
    import com.hn.lz.model.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheConfig;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import java.util.List;
    
    /**
     * Created by mll on 2018/6/21.
     */
    @CacheConfig(cacheNames = "user")
    @Service
    public class UserService {
    
        @Autowired
        private UserMapper userMapper;
    
        // ----------------------------------  数据操作 BEGIN  --------------------------------------
        /**
         * 插入数据
         * @param data
         * @return
         */
        @Transactional
        @CachePut(key = "#data.id")
        public User insert(User data){
            userMapper.insert(data);
            return data;
        }
    
        /**
         * 更新数据
         * @param data
         * @return
         */
        @Transactional
        @CachePut(key = "#data.id")
        public User update(User data){
            userMapper.updateByPrimaryKeySelective(data);
            return data;
        }
    
        /**
         * 删除数据
         * @param id
         * @return
         */
        @Transactional
        @CacheEvict(key = "#id")
        public int delete(String id){
            int result = userMapper.deleteByPrimaryKey(id);
            return result;
        }
    
        /**
         * 得到所有数据列表
         * @return
         */
        public List<User> select() {
            List<User> list = userMapper.selectAll();
            return list;
        }
    
        /**
         * 根据id查询数据
         * @param id
         * @return
         */
        @Cacheable(key = "#id")
        public User query(String id){
            User data = userMapper.selectByPrimaryKey(id);
            return data;
        }
        // ----------------------------------  数据操作 END  --------------------------------------
    }
    

    六、要点

    1、注解

    • @CacheConfig这个注解主要用于配置该类中会用到的一些公用的缓存配置。我们也可以不使用该注解,直接通过自己的注解配置缓存集的名字来定义。
    @CacheConfig(cacheNames = "user")
    @Service
    public class UserService
    
    • @CachePut这个注解直接将返回值放入缓存中,通常用于保存和修改方法中。
    • value缓存的名称,必须指定至少一个。
    • key缓存的 key,可以为空,如果指定要按照 SpEL(Spring Expression Language) 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。
    • condition:缓存的条件,可以为空,使用 SpEL 编写,返回true或者false只有为true才进行缓存。
    @CachePut(value = "user", key = "#data.id", condition = "#result.username ne 'zhang'")  
    public User insert(User data)  
    
    • @Cacheable这个注解在执行前先查看缓存中是不是已经存在了,如果存在,直接返回。如果不存在,将方法的返回值放入缓存。
    • value缓存的名称,必须指定至少一个。
    • key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。
    • condition缓存的条件,可以为空,使用 SpEL 编写,返回true或者false只有为true才进行缓存。
    @Cacheable(value = "user", key = "#id", condition = "#id lt 10")  
    public User query(Long id)  
    
    • @CacheEvict这个注解在执行方法执行成功后会从缓存中移除。
    • value缓存的名称,必须指定至少一个。
    • key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合。
    • condition缓存的条件,可以为空,使用 SpEL 编写,返回true或者false只有为true才进行缓存。
    • allEntries是否清空所有缓存内容,缺省为false如果指定为true则方法调用后将立即清空所有缓存。
    • beforeInvocation是否在方法执行前就清空,缺省为false如果指定为true则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存。
    @CacheEvict(value = "user", key = "#data.id", beforeInvocation = false, condition = "#result.username ne 'zhang'")  
    public User delete(User data) 
    
    • @Caching这个注解组合多个Cache注解使用,并且可以自定义注解使用。
    @Caching(  
            put = {  
                    @CachePut(value = "user", key = "#user.id"),  
                    @CachePut(value = "user", key = "#user.username"),  
                    @CachePut(value = "user", key = "#user.email")  
            }  
    )  
    
    @Caching(  
            put = {  
                    @CachePut(value = "user", key = "#user.id"),  
                    @CachePut(value = "user", key = "#user.username"),  
                    @CachePut(value = "user", key = "#user.email")  
            }  
    )  
    @Target({ElementType.METHOD, ElementType.TYPE})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Inherited  
    public @interface MyCache {  
    }  
    
    @MyCache 
    public User save(User data)
    

    2、Spring Cache提供了一些供我们使用的SpEL上下文数据

    名字 描述 示例
    methodName 当前被调用的方法名 #root.methodName
    method 当前被调用的方法 #root.method.name
    target 当前被调用的目标对象 #root.target
    targetClass 当前被调用的目标对象类 #root.targetClass
    args 当前被调用的方法的参数列表 #root.args[0]
    caches 当前方法调用使用的缓存列表(如@Cacheable(value={"cache1", "cache2"})),则有两个cache #root.caches[0].name
    argument name 当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数 #user.id
    result 方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,'cache evict'的beforeInvocation=false) #result

    3、Redis常用命令

    flushdb:清空当前数据库。
    select index:选择索引数据库,index为索引值名,如:select 1
    del key:删除一条指定key的值。
    keys *:查看数据库内所有的key。
    flushall:清空所有数据库。
    quit:退出客户端连接。

    相关文章

      网友评论

          本文标题:三、SpringBoot 2.x 使用Redis作为项目数据缓存

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