轻松封装Spring Boot Redis操作:使用泛型工具类实现简洁的Redis访问(9)

1,234 阅读3分钟

初识 Redis

Redis是一种Key-Value类型的内存数据库,类似于memcached,但是具有更多的特性。它的整个数据库操作在内存中进行,通过异步操作将数据库数据定期写入硬盘进行保存。由于是纯内存操作,因此Redis具有出色的性能,每秒可以处理超过10万次读写操作,是已知性能最快的Key-Value DB。除此之外,Redis最大的魅力在于其支持保存多种数据结构,并且单个value的最大限制是1GB,不像memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。Redis默认有16个数据库,类似于数组下标是从零开始,初始默认使用零号库,支持统一的密码管理,所有库都是同样密码,要么都能连接,要么一个也连接不上。Redis默认端口是6379。

Redis的优点主要包括:

  • 速度快:因为数据存在内存中,类似于HashMap,查找和操作的时间复杂度都是O(1);
  • 持久化:定期通过异步操作把数据库数据写到硬盘上进行保存;
  • 支持丰富的数据类型:支持string、list、set、sorted set、hash;
  • 支持事务:操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行;
  • 丰富的特性:可用于缓存、消息、按key设置过期时间,过期后将会自动删除等。

Spring Boot 集成

在Spring Boot中引入Redis的方式非常简单,只需添加相关的依赖即可。封装Redis泛型工具类的目的是为了方便代码的复用,使得我们在项目中使用Redis时更加便捷。泛型工具类的核心思想是通过泛型来实现代码的复用,将Redis的一些常用操作封装在一起,方便我们在项目中直接调用

  • pom.xml 文件中引入 spring-boot-starter-data-redis 依赖

            <!--redis-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
  • 指定GenericJackson2JsonRedisSerializer序列化方式

    @Configuration
    public class RedisConfig {
        @Bean
        public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
            RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            StringRedisSerializer stringRedisSerializer=new StringRedisSerializer();
            GenericJackson2JsonRedisSerializer serializer=new GenericJackson2JsonRedisSerializer();
            redisTemplate.setKeySerializer(stringRedisSerializer);
            redisTemplate.setHashKeySerializer(stringRedisSerializer);
            redisTemplate.setValueSerializer(serializer);
            redisTemplate.setHashValueSerializer(serializer);
            return redisTemplate;
        }
    }
    
  • 配置Redis

    spring.redis.host=localhost
    spring.redis.port=6379
    #密码
    #spring.redis.password=
    #连接池最大连接数
    spring.redis.lettuce.pool.max-active=20
    #连接池最大空闲连接数
    spring.redis.lettuce.pool.max-idle=10
    #连接池最小空闲连接数
    spring.redis.lettuce.pool.min-idle=5
    #连接池最大阻塞时间
    spring.redis.lettuce.pool.max-wait=PT10S
    #链接超时时间
    spring.redis.timeout=PT10S
    
  • RedisUtil 实现

    @Component
    public class RedisUtil {
        @Resource
        private  RedisTemplate redisTemplate;
    ​
        /**
         * 是否存在key
         */
        public Boolean hasKey(String key) {
            if (null==key){
                return false;
            }
            return redisTemplate.hasKey(key);
        }
    ​
        /**
         * 删除key
         */
        public Boolean delete(String key) {
            if (null==key){
                return false;
            }
            return redisTemplate.delete(key);
        }
    ​
        /**
         * 批量删除key
         * @throws
         */
        public Long delete(Collection<String> keys) {
            return redisTemplate.delete(keys);
        }
    ​
    ​
        /**
         * 设置过期时间
         * @throws
         */
        public Boolean expire(String key, long timeout, TimeUnit unit) {
            if (null==key||null==unit){
                return false;
            }
            return redisTemplate.expire(key, timeout, unit);
        }
    ​
    ​
    ​
        /**
         * 移除 key 的过期时间,key 将持久保持
         * @throws
         */
        public Boolean persist(String key) {
            if (null==key){
                return false;
            }
            return redisTemplate.persist(key);
        }
    ​
        /**
         * 返回 key 的剩余的过期时间
         *当 key 不存在时,返回 -2 。
         * 当 key 存在但没有设置剩余生存时间时,返回 -1 。
         * 否则,以秒为单位,返回 key的剩余生存时间
         * @throws
         */
        public Long getExpire(String key, TimeUnit unit) {
            if(null==key||null==unit){
                return -2L;
            }
            return redisTemplate.getExpire(key, unit);
        }
    ​
        /**
         * 判断redis中指定key的Hash值是否存在
         *
         * @param key   键
         * @param field hash键
         * @return 是否存在
         */
        public boolean hasKey(String key, String field) {
            return redisTemplate.opsForHash().hasKey(key, field);
        }
    ​
    ​
        /**
         * string 类型set 方法
         * @param key
         * @param value
         * @param <T>
         */
        public <T> void set(String key, T value) {
            redisTemplate.opsForValue().set(key, value);
        }
    ​
        /**
         * string 类型get方法
         * @param key
         * @param <T>
         * @return
         */
        public <T> T get(String key) {
            ValueOperations<String, T> ops = redisTemplate.opsForValue();
            return ops.get(key);
    ​
        }
    ​
        /**
         * 弹出最左边的元素,弹出之后该值在列表中将不复存在
         * @param key   键
         * @return  弹出的值
         */
        public <T> T leftPop(final String key) {
            ListOperations<String, T> opsForList = redisTemplate.opsForList();
            return opsForList.leftPop(key);
        }
    ​
    ​
        /**
         * 将List类型的数据添加到Redis中。
         * @param key
         * @param values
         * @param <T>
         */
        public <T> void putList(String key, List<T> values) {
            redisTemplate.opsForList().rightPushAll(key, values);
        }
    ​
        /**
         * 获取指定key的List类型的数据
         * @param key
         * @param <T>
         * @return
         */
        public <T> List<T> getList(String key,long start, long end) {
            ListOperations<String, T> opsForList=redisTemplate.opsForList();
            return opsForList.range(key, start, end);
        }
    ​
    ​
        /**
         *返回并弹出指定Key关联的链表中的最后一个元素,即尾部元素
         * 弹出后值将不存在
         * @param key
         * @param <T>
         * @return
         */
        public <T> T rightPop(String key){
            ListOperations<String, T> opsForList=redisTemplate.opsForList();
            return opsForList.rightPop(key);
        }
    ​
        /**
         * 将Set类型的数据添加到Redis中
         * @param key
         * @param values
         * @param <T>
         */
        public <T> void putSet(String key, Set<T> values) {
            redisTemplate.opsForSet().add(key, values.toArray());
        }
    ​
        /**
         * 获取指定key的Set类型的数据
         * @param key
         * @param <T>
         * @return
         */
        public <T> Set<T> getSet(String key) {
            SetOperations<String, T> opsForSet=redisTemplate.opsForSet();
            return opsForSet.members(key);
        }
    ​
        /**
         * 将Map类型的数据添加到Redis中。
         * @param key
         * @param map
         * @param <K>
         * @param <V>
         */
        public <K, V> void putHash(String key, Map<K, V> map) {
            redisTemplate.opsForHash().putAll(key, map);
        }
    ​
        /**
         * 获取指定key的Map类型的数据。
         * @param key
         * @param <K>
         * @param <V>
         * @return
         */
        public <K, V> Map<K, V> getHash(String key) {
            HashOperations<String,K,V> opsForHash= redisTemplate.opsForHash();
            return opsForHash.entries(key);
        }
    ​
        /**
         * 删除hash key 内指定字段
         * @param key
         * @param field
         * @return
         */
        public Long deleteHashKey(String key,String field) {
            return redisTemplate.opsForHash().delete(key,field);
        }
    ​
    }
    ​