• spring boot 整合redis


    前言

      本文只适用于初学redis的同学,旨在能够运行项目即可,想进行深入了解的同学,本文可能不会给你带来任何价值

    准备工作

      1.本文中涉及的项目是基于spring boot2.x,并且配置了web模块,在开始之前请准备好你的代码环境。

      2.同时,暂时请忘掉你在之前查阅过的,不能使你的项目正常运行的文章。因为一些先入为主的概念,可能会让你变得疑惑,请完全跟随本文的脚步

    你必须要了解的一些关系

      1.springboot整合redis的两种连接方式

        jedis:多线程下,非线程安全,所以使用连接池(不支持异步操作),适用springboot1.x

        lettuce:多线程下,线程安全,基于Netty支持异步操作,适用springboot2.x0

      2. spring boot2.x 默认使用lettuce连接,spring-boot-starter-data-redis集成了lettuce-core,引入spring-boot-starter-data-redis之后就不需要引入lettuce-core了,但是版本的lettuce-core需要commons-pool2。

      3.本文项目使用lettuce方式连接

    所需的依赖

         //<!--redis-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    //<!-- 高版本redis的lettuce需要commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency>

    在application.properties中添加配置

    //application.properties
    #我们这里只配置必须的一些配置,先让项目运行起来,在做拓展 #配置redis信息 #redis服务器地址 spring.redis.host
    =127.0.0.1 #redis服务器端口 spring.redis.port=6379 spring.redis.password=123456789

    在application.properties配置后,并不意味着,spring boot会自动为我们配置redis连接,我们还需要定义一个配置类RedisConf

    package com.example.demo;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    
    @Configuration //使用注解注入配置,必须要添加,这样application.properties中的配置才能在redis中生效,添加@Configuration之后,spring 会自动扫描注入
    public class RedisConf {
        @Bean //声明一个Bean 这样其他地方可以通过@Autowired获取到生成的 RedisTemplate 对象
        public RedisTemplate rt(RedisConnectionFactory factory) {
            RedisTemplate template = new RedisTemplate();
            template.setConnectionFactory(factory);// 配置连接工厂
          //设置键值默认序列化方式
         RedisSerializer stringSerializer = new StringRedisSerializer(); //RedisTemplate有自己的默认序列化的方式,不过使用默认方式,会在redis客户端查看的时候出现乱码,不便与使用,我们这里用falstjson库
         template.setDefaultSerializer(stringSerializer);

    return template; } }

     测试是否成功

    package com.example.demo;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.concurrent.TimeUnit;
    
    @RestController
    public class Index {
    
    
        @Autowired
        RedisTemplate rt; //装配之前定义的@bean
    
        @RequestMapping("/index")
        public String index() {
            //测试redis 是否配置成功
            rt.opsForValue().set("key001", "测试数据 key值是key001", 500, TimeUnit.MINUTES);
            System.out.println(rt.opsForValue().get("key001"));
            return "执行成功";
        }
    }

    拓展

      1.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.jedis.pool.max-active=20
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=10
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    # 连接超时时间(毫秒)
    spring.redis.timeout=1000

      2.RedisTemplate 常用方法

          前言:

            redis有五种数据类型,下文中的rt为RedisTemplate实例对象。

            redis的key值是唯一的,如果为String设置了key001,那么hash类型数据中就不可以在加入key001的key

          常用方法:

            1. string

              (1)增

        //写入一个键和值 key,value;如果已经存在key那么会覆盖已有的key值
        rt.opsForValue().set(key, "value");
    
        //写入一个key-value,并且设置它的过期时间
           rt.opsForValue().set(key, value, 1000, TimeUnit.MILLISECONDS);
    
        //将map中的key-value批量添加为redis的key-value;只要redis中已经存在与map相同的key(一个或者多个),那么map中的key-value都不会写入redis;注入成功返回ture,失败则返回false
           Map valMap = new HashMap();
           rt.opsForValue().multiSetIfAbsent(valMap);
    
        //将map中的值批量注入redis,和multiSetIfAbsent效果一直,不同的是multiSet,即便redis已经存在map中相同的key,也用map的值会覆盖掉redis中原有的key的值,所以这个方法可以用于key的批量增加,和修改; 无返回值
           rt.opsForValue().multiSet(valMap);

              (2)删

         //删除指定的key
            rt.delete(key);
    
            //批量删除key,其中keys:Collection<K> keys
            rt.delete(keys);

              (3)改

         // ps:经测试 无效; 在指定key值后增加字符串
            rt.opsForValue().append(key, "新增字符串");
    
            //为key设置过期时间(倒计时),到时间后直接删除key,而非把值变为null
            rt.expire(key, 2000, TimeUnit.MILLISECONDS);
    
            //你也可以直接设置到期的时间 过期直接删除key
            rt.expireAt(key, new Date());
    
            //如果久的key名存在,则将旧的key名改成新的key名;如果不存在旧的key,那么会抛出异常
            rt.rename(oldKey, newKey);
    
            //将指定的key,移动到指定的redis数据库中,dbIndex:redis数据库索引
            rt.move(key, dbIndex);
    
            //将key值转化成byte[],return:byte[],如果不存在key,那么return:null
            rt.dump(key); 

              

              (4)查

         //判断是否存在key,return:boolean,存在key返回true,不存在返回false
            rt.hasKey(key); 
    
            //批量获取key值,返回一个list<>;
            rt.opsForValue().multiGet(keys);
    
            //通过正则查找匹配的key值,返回一个set集合类型
            rt.keys(Pattern.compile(key).pattern());
    
            //获取对应key的值,return:string ,不存在key则null
            rt.opsForValue().get(key);
    
            //返回对应key所储存的值的类型
            rt.type(key);
    
            //随机取出一个key
            rt.randomKey();
    
            //设置key过期时间
            rt.expire(key, 1000, TimeUnit.MILLISECONDS);
    
            //返回对应key值剩余的过期时间,如果不存在key返回-2;如果没有通过expire设置过期时间,则返回-1,表示永久保存
            rt.getExpire(key);
            rt.getExpire(key, TimeUnit.MILLISECONDS);//可以通过第二个参数,设置放回剩余过期时间的单位
    
            //查询对应key的大小,单位为byte
            rt.opsForValue().size(key);

            2. hash

              (1)增、改

        //在对应key的hash表中注入一个字段为field,值为hash val 001的记录;如果对应key已经存在hash表则在hash表中注入字段;如果hash表中字段已经存在相同,则覆盖对应字段的value
            rt.opsForHash().put(key, field, "hash val 00");
    
            //在对应key的hash表内,增加一个字段filed,并设置对应字段的filed;仅当对应的filed不存在时才设置
            rt.opsForHash().putIfAbsent(key, field, "hash val 01");
    
            //批量添加对应key下hash表中的记录
            Map m = new HashMap();
            m.put("filed01", "val3");
            m.put("filed02", "val4");
            rt.opsForHash().putAll(key, m);//如果hash表中已经存在相同的字段,那么对字段的值进行覆盖

              

              (2)删

         //删除对应hash表内的一个或多个字段
            rt.opsForHash().delete(key, field);
            String[] str = {"filed01", "filed02"};
            rt.opsForHash().delete(key, str);

              (3)改

          //删除对应hash表内的一个或多个字段
            rt.opsForHash().delete(key, field);
            String[] str = {"filed01", "filed02"};
            rt.opsForHash().delete(key, str);

              (4)查

        //查看指定hash表内的指定字段是否存在
            rt.opsForHash().hasKey(key, field);
    
            //查询对应key的hash表中的field字段的值
            rt.opsForHash().get(key, field);
    
            //获取对应key的hash表的所有的字段名
            rt.opsForHash().keys(key);
    
            //获取对应key的hash表中的所有字段和值对
            rt.opsForHash().entries(key);

            3. list

              (1)增

         //在key对应的list的开头位置插入一个元素
            rt.opsForList().leftPush(key, "第1次插入的元素");
            rt.opsForList().leftPush(key, "指定值", "第2次插入的元素");//在list从左到右顺序,第一个值是"指定值"的元素前面插入值
    
            //在key对应的list的开头位置插入一个元素,不同的是,只有key对应的list存在时,才插入
            rt.opsForList().leftPushIfPresent(key, "插入的值");
    
    
            //在对应key的list中的开头位置批量增加元素;请注意:插入的元素中,越靠前的元素越先插入,这就意味者在list中越晚插入的元素排序位置越靠前
            rt.opsForList().leftPushAll(key, "批量插入元素1", "批量插入元素2");
            Collection<String> items = new ArrayList<>();
            items.add("items01");
            items.add("items02");
            rt.opsForList().leftPushAll(key, items);//也可以使用集合的方式批量插入
    
            //在对应key的list中的末尾添加元素,和leftPush使用完全一致
            rt.opsForList().rightPush(key, "在末尾添加元素");
    
            //在末尾批量添加元素,和leftPushAll使用完全一致,区别是一个是在开头插入,一个实在末尾插入
            rt.opsForList().rightPushAll(key, "末尾添加元素1");

              (2)删

         //删除从0开始第一个值值为value的元素
            rt.opsForList().remove(key, 0, value);
    
            //只保留对应key的list中index到pivot位置中的元素
            rt.opsForList().trim(key, index, pivot);
    
            //移除key对应的list的第一个元素
            rt.opsForList().leftPop(key);
            rt.opsForList().leftPop(key, 5000, TimeUnit.MILLISECONDS);//设置三个参数之后,如果没有存在可移除的元素,那么会阻塞当前进程,直到纯在可以移除的元素,或者到达设置的超时时间为止
    
            //移除key对应list的最后一个元素
            rt.opsForList().rightPop(key);
            rt.opsForList().rightPop(key, 1000, TimeUnit.MILLISECONDS);
    
            //将key1对应的list的最后一个元素移除,并将其插入key2对应的list的最开头的位置
            rt.opsForList().rightPopAndLeftPush(key1, key2);
            rt.opsForList().rightPopAndLeftPush(key1, key2, 1000, TimeUnit.MILLISECONDS);//设置三个参数之后,如果没有存在可移除的元素,那么会阻塞当前进程,直到纯在可以移除的元素,或者到达设置的超时时间为止

              (3)改

          //设置指定元素的值
            rt.opsForList().set(key, 0, "添加元素 魔改");
    
            //键list中指定位置的元素保留,其余的全部删除
            rt.opsForList().trim(key, 0, 5);

              (4)查

        //获取对应key的list中指定index的元素
            rt.opsForList().index(key, index);
    
            //获取对应key的list中指定范围的元素
            rt.opsForList().range(key, 0, -1);
    
            //获取key对应的list内部元素数量
            rt.opsForList().size(key);

            4. set

              (1)增、改

         //在key对应的set中增加一个元素或多个元素
            rt.opsForSet().add(key, value, "value2", "value3", "value5", "value6", "value7");

              (2)删

         //删除key对应的set中一个或多个value
            rt.opsForSet().remove(key, value, value2);
    
            //删除set随机的一个元素,并将其返回
            rt.opsForSet().pop(key);

              (3)查

         //获取集合中所有的元素
            rs = rt.opsForSet().members(key);
    
            //判断集合中是否存在指定的value
            rt.opsForSet().isMember(key, value);
    
            //判断多个个集合的交集,只返回所有集合中都存在的元素
            rt.opsForSet().intersect(key, key2);
            rt.opsForSet().intersect(key, keys);
    
            //将key对应的与一个或多个集合中的交集储存到destKey集合中
            rt.opsForSet().intersectAndStore(key, key2, destKey);//将key与key2对应集合中元素的交集凡在放在destKey中
            rt.opsForSet().intersectAndStore(key, keys, destKey);//将key与keys中多个集合中对应的元素的交集放在destKey中
    
            //获取集合中的差集
            rt.opsForSet().difference(key, key2);//比较两个集合的差集
            rt.opsForSet().difference(key, keys);//比较多个集合的差集
    
            //随机获取集合中的一个元素
            rt.opsForSet().randomMember(key);
    
            //随机获取集合中指定个数的元素
            rt.opsForSet().randomMembers(key, count);
    
            //获取集合内部元素数量
            rt.opsForSet().size(key);

            

            5.zSet

              (1)增

                

         //在key对应的zSet集合中增加一个元素,score:int 0;在增加元素的过程中,如果zSet已经存在相同的value的元素,那么旧元素的score将会被覆盖
            rt.opsForZSet().add(key, value, score);

              (2)删

         //删除对应的元素;
            rt.opsForZSet().remove(key, value);
            rt.opsForZSet().remove(key, value, value2);//批量删除元素
    
            //移除指定索引位置的元素
            rt.opsForZSet().removeRange(key, start, end);
    
            //移除指定score范围内的元素
            rt.opsForZSet().removeRangeByScore(key,min,max);//移除指定score范围内的元素

              (3)改

          //改变元素的score值
            rt.opsForZSet().incrementScore(key, value, 99);
    
            //获取多个集合的并集,并将其存储在另一个集合中
            rt.opsForZSet().unionAndStore(key, keys, key2);//keys:为字符串或者字符串集合,为字符串集合的时候合并多个集合
    
            //获取多个集合的交集,并将其存储在另一个集合中
            rt.opsForZSet().intersectAndStore(key, keys, key2);//使用方式和unionAndStore完全一致

              (4)查

         //返回指定index范围的元素
            int start = 0;
            int end = -1;
            rt.opsForZSet().reverseRangeWithScores(key, start, end);
    
            //返回元素在集合的排名;排名值为元素从小到大的排列位置,从0号位开始;
            rt.opsForZSet().rank(key, value);
    
            //返回元素在集合的排名,和rank一样,只不过是由大到小排列
            rt.opsForZSet().reverseRank(key, value);
    
            //返回指定score范围的元素,
            rt.opsForZSet().reverseRangeByScore(key, 0, 100);//返回score是0-100得元素
            rt.opsForZSet().reverseRangeByScore(key, 0, 100, start, count);//可以添加参数,获取指定score区间内,从start号位开始的count个元素
    
            //根据score获取集合元素数量
            rt.opsForZSet().count(key, 0, 10);
    
            //获取zSet中集合的数量
            rt.opsForZSet().size(key);
    
            //获取集合中对应得score值
            rt.opsForZSet().score(key, value);
  • 相关阅读:
    POJ3977 Subset 折半枚举
    Ubuntu和Win7双系统,ubuntu被删,重新启动之后显示,no such partition
    hdu 4296 贪心
    Python标准库:内置函数tuple([iterable])
    【python自制】让大白成为你的个人助手!
    Flex设置LinkButton的背景色
    VB6基本数据库应用(五):数据的查找与筛选
    正态分布(normal distribution)与偏态分布(skewed distribution)
    windows 系统文件 —— 特殊文件及文件类型
    windows 系统文件 —— 特殊文件及文件类型
  • 原文地址:https://www.cnblogs.com/wrhbk/p/15067093.html
Copyright © 2020-2023  润新知