美文网首页
SpringBoot Web项目使用Redis

SpringBoot Web项目使用Redis

作者: PC_Repair | 来源:发表于2018-10-29 15:30 被阅读50次
    • pom.xml导入maven依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    • application-redis.properties配置springboot的redis环境
    # Redis数据库索引(默认为0)
    spring.redis.database=0  
    # Redis服务器地址
    spring.redis.host=127.0.0.1
    # Redis服务器连接端口
    spring.redis.port=6379  
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接池最大连接数(使用负值表示没有限制)
    spring.redis.pool.max-active=8  
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.pool.max-wait=-1  
    # 连接池中的最大空闲连接
    spring.redis.pool.max-idle=8  
    # 连接池中的最小空闲连接
    spring.redis.pool.min-idle=0  
    # 连接超时时间(毫秒)
    #spring.redis.timeout=0
    
    • RedisConfig配置文件
    package com.ljf.blog.config;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.cache.RedisCacheWriter;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.*;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import org.springframework.cache.interceptor.KeyGenerator;
    
    import java.lang.reflect.Method;
    import java.time.Duration;
    
    /**
     * Created by lujiafeng on 2018/10/16.
     */
    
    @Configuration
    @EnableCaching //spring framework中的注解驱动的缓存管理功能
    public class RedisConfig extends CachingConfigurerSupport {
    
        /**
         * 生成key的策略
         * @return
         */
        @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().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
    
        /**
         * 设置redis作为默认缓存工具
         * @param connectionFactory
         * @return
         */
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
            return RedisCacheManager
                    .builder(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory))
                    .cacheDefaults(redisCacheConfiguration).build();
        }
    
        /**
         * RedisTemplate配置
         * @param factory
         * @return
         */
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            // 配置连接工厂
            template.setConnectionFactory(factory);
    
            // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
            Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
    
            ObjectMapper om = new ObjectMapper();
            // 指定要序列化的域,field、get和set,以及修饰范围,ANY是都包括private和public
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String、Integer等会抛出异常
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jacksonSeial.setObjectMapper(om);
    
            // 值采用json序列化
            template.setValueSerializer(jacksonSeial);
            // 使用StringRedisSerializer来序列化和反序列化redis的key值
            template.setKeySerializer(new StringRedisSerializer());
    
            // 设置hash的 key 和 value 序列化模式
            template.setHashKeySerializer(new StringRedisSerializer());
            template.setHashValueSerializer(jacksonSeial);
            template.afterPropertiesSet();
    
            return template;
        }
    
        /**
         * 对Hash类型的数据操作
         * @param redisTemplate
         * @return
         */
        @Bean
        public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForHash();
        }
    
        /**
         * 对redis字符串类型的数据操作
         * @param redisTemplate
         * @return
         */
        @Bean
        public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForValue();
        }
    
        /**
         * 对链表类型的数据操作
         * @param redisTemplate
         * @return
         */
        @Bean
        public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForList();
        }
    
        /**
         * 对无序集合类型的数据操作
         * @param redisTemplate
         * @return
         */
        @Bean
        public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForSet();
        }
    
        /**
         * 对有序集合类型的数据操作
         * @param redisTemplate
         * @return
         */
        @Bean
        public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForZSet();
        }
    
    }
    
    • RedisService类编写
    package com.ljf.blog.service.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.Collection;
    import java.util.Date;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    /**
     * Created by lujiafeng on 2018/10/16.
     */
    
    @Component
    public class RedisService {
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        /**
         * 默认过期时长,单位:秒
         */
        public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
    
        /**
         * 不设置过期时长
         */
        public static final long NOT_EXPIRE = -1;
    
        /**
         * 判断key是否存在
         * @param key
         * @return
         */
        public boolean existsKey(String key) {
            return redisTemplate.hasKey(key);
        }
    
        /**
         * 重命名key,如果newKey已经存在,则newKey的原值被覆盖
         * @param oldKey
         * @param newKey
         */
        public void renameKey(String oldKey, String newKey) {
            redisTemplate.rename(oldKey, newKey);
        }
    
        /**
         * newKey不存在时才重命名
         * @param oldKey
         * @param newKey
         * @return
         */
        public boolean renameKeyNotExist(String oldKey, String newKey) {
            return redisTemplate.renameIfAbsent(oldKey, newKey);
        }
    
        /**
         * 删除key
         * @param key
         */
        public void deleteKey(String key) {
            redisTemplate.delete(key);
        }
    
        /**
         * 删除多个key
         * @param keys
         */
        public void deleteKeys(String... keys) {
            Set<String> kSet = Stream.of(keys).map(k -> k).collect(Collectors.toSet());
            redisTemplate.delete(kSet);
        }
    
        /**
         * 删除Key的集合
         * @param keys
         */
        public void deleteKeys(Collection<String> keys) {
            Set<String> kSet = keys.stream().map(k -> k).collect(Collectors.toSet());
            redisTemplate.delete(kSet);
        }
    
        /**
         * 设置key的生命周期
         * @param key
         * @param time
         * @param timeUnit
         */
        public void expireKey(String key, long time, TimeUnit timeUnit) {
            redisTemplate.expire(key, time, timeUnit);
        }
    
        /**
         * 指定key的生命周期
         * @param key
         * @param date
         */
        public void expireKeyAt(String key, Date date) {
            redisTemplate.expireAt(key, date);
        }
    
        /**
         * 将key设置为永久有效
         * @param key
         */
        public void persistKey(String key) {
            redisTemplate.persist(key);
        }
    }
    
    • RedisKeyUtil工具类
    package com.ljf.blog.util;
    
    /**
     * Created by lujiafeng on 2018/10/25.
     */
    public class RedisKeyUtil {
    
        /**
         * redis的key
         * 形式为:
         * 表名:主键名:主键值:列名
         * @param tableName 表名
         * @param majorKey 主键名
         * @param majorKeyValue 主键值
         * @param column 列名
         * @return
         */
        public static String getKeyWithColumn(String tableName, String majorKey, String majorKeyValue, String column) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(tableName).append(":");
            buffer.append(majorKey).append(":");
            buffer.append(majorKeyValue).append(":");
            buffer.append(column);
            return buffer.toString();
        }
    
        /**
         * 自定义生成redis的key
         * 形式为:
         * 表名:主键名:主键值
         * @param tableName
         * @param majorKey
         * @param majorKeyValue
         * @return
         */
        public static String getKey(String tableName, String majorKey, String majorKeyValue) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(tableName).append(":");
            buffer.append(majorKey).append(":");
            buffer.append(majorKeyValue);
            return buffer.toString();
        }
    
    }
    
    使用示例
        @Override
        public Content getArticle(String id) {
            //先从redis中读取文章信息
            String contentKey = RedisKeyUtil.getKey(ContentKey.TABLE_NAME, ContentKey.MAJOR_KEY, id);
            Content content = (Content) valueOperations.get(contentKey);
            if (content != null) {
                System.out.println("从redis读取数据");
            }
            if (content == null) {
                System.out.println("从mysql读取数据");
                if (StringUtils.isNotBlank(id)) {
                    if (Tools.isNumber(id)) {
                        content = contentMapper.selectByPrimaryKey(Integer.valueOf(id));
                        if (null != content) {
                            content.setHits(content.getHits() + 1);
                            contentMapper.updateByPrimaryKey(content);
                        }
                        System.out.println("将查询数据插入redis");
                        valueOperations.set(contentKey, content);
                        redisService.expireKey(contentKey, ContentKey.LIVE_TIME, TimeUnit.HOURS);
                        return content;
                    } else {
                        ContentExample example = new ContentExample();
                        example.createCriteria().andSlugEqualTo(id);
                        List<Content> contents = contentMapper.selectByExampleWithBLOBs(example);
                        if (contents.isEmpty()) {
                            throw new TipException("query content by id and return is not one");
                        }
                        content = contents.get(0);
                        System.out.println("将查询数据插入redis");
                        valueOperations.set(contentKey, content);
                        redisService.expireKey(contentKey, ContentKey.LIVE_TIME, TimeUnit.HOURS);
                    }
                }
            }
            return content;
        }
    

    相关文章

      网友评论

          本文标题:SpringBoot Web项目使用Redis

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