Spring Boot 整合——RedisTemplate使用基础

spring-boot-starter-data-redis

spring-boot-starter-data-redis是Spring对redis一系列操作进行的封装。它简化了很多redis的操作,
让开发的精力更多的投入在业务上面。

依赖的引入

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.6.2</version>
        </dependency>
    </dependencies>

参数配置

spring:
  application:
    name: redis
  redis:
    database: 0
    host: 127.0.0.1
    jedis:
      pool:
        #最大连接数据库连接数,设 0 为没有限制
        max-active: 8
        #最大等待连接中的数量,设 0 为没有限制
        max-idle: 8
        #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
        max-wait: -1ms
        #最小等待连接中的数量,设 0 为没有限制
        min-idle: 0
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        max-wait: -1ms
        min-idle: 0
      shutdown-timeout: 1000ms
    password: 你的密码
    port: 6379

server:
  port: 8000

redis的操作

spring-boot-starter-data-redis提供了两个操作Redis的工具,StringRedisTemplate
RedisTemplate两者的区别主要有下面

  1. StringRedisTemplate是RedisTemplate的子类
  2. 两者使用了不同的序列化类,RedisTemplate使用的是JdkSerializationRedisSerializer,StringRedisTemplate使用的是StringRedisSerializer。
  3. StringRedisTemplate更加专注于字符串的操作,而RedisTemplate提供了更多的数据类型的操作。
  4. RedisTemplate将数据保存到Redis中的时候会将值和键都序列化成字节数组进行保存。

RedisTemplate支持的数据类型

因为StringRedisTemplate是继承于RedisTemplate的所以,目前主要介绍StringRedisTemplate

操作字符串

redisTemplate.opsForValue();

操作hash

redisTemplate.opsForHash();

操作list

redisTemplate.opsForList();

操作set

redisTemplate.opsForSet();

操作ZSet(有序set)

redisTemplate.opsForZSet();

操作Geo(地图信息)

redisTemplate.opsForGeo();

操作HyperLogLog(HyperLogLog算法)

redisTemplate.opsForHyperLogLog()

基础操作

公共方法
设置过期时间

redisTemplate提供了expire来设置某个key的过期时间

    @Override
    public void setExpire(String key, long timeout, TimeUnit unit) {
        //设置超时时间10秒 第三个参数控制时间单位,详情查看TimeUnit
        redisTemplate.expire(key,timeout,unit);
    }
删除某个key的内容

redisTemplate提供了delete来删除某个key

 /**
     * 删除某个Key
     * @param key
     * @param timeout
     * @param unit
     */
    @Override
    public void remove(String key, long timeout, TimeUnit unit) {
        //设置超时时间10秒 第三个参数控制时间单位,详情查看TimeUnit
        redisTemplate.delete(key);
    }
对字符串的操作

对字符串的操作应该算是Redis最基础的功能了

设置和取出字符串内容

    @Override
    public void setData(String key,String value) {
        stringRedisTemplate.opsForValue().set(key,value);
    }

    @Override
    public String getData(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }
对List的操作

根据源码可以看到从redis中取出的的确是list但是Spring封装了一些模仿Deque的方法,实现了双端操作

    /**
     * 操作list的操作
     * @param key
     * @param value
     * @param location
     */
    @Override
    public void setListData(String key,String value,ListLocation location) {
        if (ListLocation.LEFT.equals(location)) {
            // 也可以这么设置 redisTemplate.boundListOps(key).leftPush(key,value);
            redisTemplate.opsForList().leftPush(key,value);
        } else {
            redisTemplate.opsForList().rightPush(key,value);
        }
    }

    /**
     * 获得list的值
     * @param key
     * @param location
     * @return
     */
    @Override
    public Object getListData(String key,ListLocation location) {
        if (ListLocation.LEFT.equals(location)) {
            return redisTemplate.opsForList().leftPop(key);
        } else {
            return redisTemplate.opsForList().rightPop(key);
        }
    }

使用Pop方法会取出对应位置的值并且移除它们。使用下面的测试可以很明确的发现这点。

    @Test
    public void setListData() {
        String key = "a";
        redisService.removeListData(key);
        String value = "A";
        redisService.setListData(key,value,ListLocation.LEFT);
        String value1 = "B";
        redisService.setListData(key,value1,ListLocation.LEFT);
        Object listData = redisService.getListData(key, ListLocation.LEFT);
        Assert.assertEquals("B",listData);
        Object listData2 = redisService.getListData(key, ListLocation.LEFT);
        Assert.assertEquals("A",listData2);
    }
对Hash的操作

对hash的操作基本上和我们正常操作map类似

 /**
     * 针对map类型的数据操作-设置hash的值
     * @param key
     * @param hashKey
     * @param value
     */
    @Override
    public void setHashData(String key,String hashKey,String value) {
        redisTemplate.opsForHash().put(key,hashKey,value);
    }

    /**
     * 针对map类型的数据操作-设置hash的值
     * @param key
     * @param map
     */
    @Override
    public void setHashData(String key, Map map) {
        redisTemplate.opsForHash().putAll(key,map);
    }
对Set的操作

redisTemplate提供了随机取得一个或者指定数据元素的方法,并且在取出这些元素后会被移除掉

    /**
     * set类型数据操作-设置set的值
     * @param key
     * @param value
     */
    @Override
    public void setSetData(String key,String value){
        redisTemplate.opsForSet().add(key,value);
    }

    /**
     * set类型数据操作-获得set的值
     * @param key
     * @return
     */
    @Override
    public Object getSetData(String key){
        // 随机返回并移除key对应set中某一个成员
        Object pop = redisTemplate.opsForSet().pop(key);
        // 随机返回并移除key对应set中某count个成员
        // pop(K key, long count)
        return pop;
    }
对ZSet(有序Set)的操作

ZSet是一种有序的Set,在保存数据的时候我们需要设置(double score),标识此内容的一个排序分值

然后我们使用分值范围的查询可以筛选出指定范围的内容。

    @Override
    public void setZsetData(String key,String value,Double source){
        redisTemplate.opsForZSet().add(key,value,source);
    }

    /**
     * zset类型数据操作-获得ZSet中的值
     * @param key
     * @param source1
     * @param source2
     * @return
     */
    @Override
    public Set getZsetData(String key,Double source1,Double source2){
        Set set = redisTemplate.opsForZSet().rangeByScore(key, source1, source2);
        return set;
    }

下面的测试内容中,我们分别设置了1-7的分值,然后我们查询3-6之间的数据,最后可以拿到
C、D、E、F四个内容,而且返回的数据应该是有序的。

    @Test 
    public void setZsetData() {

        redisService.setZsetData("dai","B",2D);
        redisService.setZsetData("dai","A",1D);
        redisService.setZsetData("dai","D",4D);
        redisService.setZsetData("dai","C",3D);
        redisService.setZsetData("dai","F",6D);
        redisService.setZsetData("dai","E",5D);
        redisService.setZsetData("dai","G",7D);

        Set dai = redisService.getZsetData("dai", 3D, 6D);
        Assert.assertTrue(dai.size() == 4);
        Object[] objects = dai.toArray();
        Assert.assertTrue("C".equals(objects[0]));
        Assert.assertTrue("D".equals(objects[1]));
        Assert.assertTrue("E".equals(objects[2]));
        Assert.assertTrue("F".equals(objects[3]));
    }
对Geo(地图信息)的操作

Redis在 3.2 版本提供了对Geo的支持,我们现在可以将地图信息保存到Redis中,后续可以通过范围获得符合的内容,也可以来计算距离

  /**
     * 设置Geo的值
     * @param key
     * @param location
     */
    @Override
    public void setGeoData(String key, RedisGeoCommands.GeoLocation <Object> location){
        redisTemplate.opsForGeo().add(key,location);
    }

    /**
     * 获得Geo的值
     * @param key
     * @param circle
     * @return
     */
    @Override
    public GeoResults getGeoData(String key, Circle circle){
        GeoResults radius = redisTemplate.opsForGeo().radius(key, circle);
        return radius;
    }

下面的测试内容中,我们分别设置了两个相近的坐标,然后查询500范围内只能获得一个坐标,
将范围扩大到5000便可以获得所有的坐标。

    @Test 
    public void setGeoData() {
        String key = "A";
        Point point = new Point(114.403629,30.475316);
        RedisGeoCommands.GeoLocation <Object> location = 
                new RedisGeoCommands.GeoLocation <>("软件园",point);
        Point point2 = new Point(114.386119,30.473688);
        RedisGeoCommands.GeoLocation <Object> location2 =
                new RedisGeoCommands.GeoLocation <>("财经政法",point2);
        // 保存坐标
        redisService.setGeoData(key,location);
        redisService.setGeoData(key,location2);
        redisService.setExpire(key,5000L, TimeUnit.MILLISECONDS);
        // 查询指定坐标,距离500米,此时应该只有一个坐标
        Circle circle = new Circle(114.403629,30.475316,500);
        GeoResults geoData = redisService.getGeoData(key, circle);
        List content = geoData.getContent();
        Assert.assertTrue(content.size() == 1);
        
        // 查询指定坐标,距离5000米,此时应该只有两个坐标
        Circle circle2 = new Circle(114.403629,30.475316,5000);
        GeoResults geoData2 = redisService.getGeoData(key, circle2);
        List content2 = geoData2.getContent();
        Assert.assertTrue(content2.size() == 2);
    }
HyperLogLog算法

HyperLogLog的主要作用是用来做基数统计。基数统计:一个集合中不重复元素的个数。例如集合 {“A”,“B”,“C”,“D”,“E”,“B”,“D”},它有7个元素,但它的基数为5。

 /**
     * 设置HyperLogLog的值
     * @param key
     * @param objs
     */
    @Override
    public void setHyperLogLogData(String key,Object... objs){
        redisTemplate.opsForHyperLogLog().add(key,objs);
    }

    /**
     * 获得HyperLogLog的值
     * @param key
     * @return
     */
    @Override
    public Long getHyperLogLogData(String key){
        return redisTemplate.opsForHyperLogLog().size(key);
    }

在下面的测试内容中,我们添加了values中的七个元素,但是实际中基数统计并不是7而是5

    @Test 
    public void setHyperLogLogData() {
        String key = "loglog";
        // 在HyperLogLog中实际插入的内容为A-E
        String[] values = new String[] {"A","B","C","D","E","B","D"};
        redisService.setHyperLogLogData(key,values);
        redisService.setExpire(key,3000L, TimeUnit.MILLISECONDS);
        Long hyperLogLogData = redisService.getHyperLogLogData(key);
        Assert.assertTrue(hyperLogLogData == 5);
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Long hyperLogLogData2 = redisService.getHyperLogLogData(key);
        Assert.assertTrue(hyperLogLogData2 == 0);
    }

本篇文章涉及的源码下载地址:https://gitee.com/daifyutils/springboot-samples

附录,RedisTemplate文档

RedisTemplate API 地址:https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html

RedisTemplate
方法描述
bound***Ops返回绑定到给定键的特定于(字符串、list、map、set、zset、坐标)的操作接口
convertAndSend将消息发送至指定通道中
countExistingKeys计算存在的键的数量
delete移除键
discard丢弃RedisOperations.multi()之后的操作
dump执行Redis dump并发挥结果
exec执行事务,使用默认的redisserializer反序列化字节[]或字节[]元组的集合或映射的任何结果。
execute(RedisCallback action)基于Redis连接执行操作
executePipelined在管道连接上执行给定的操作对象,返回结果。
executeWithStickyConnection分配并绑定一个新的RedisConnection
expire设置键的超时时间
expireAt设置键的超时时间,使用timestamp
getClientList请求有关已连接客户端的信息和统计信息
getDefaultSerializer返回默认序列化器
getExpire(K key)获得指定键的超时时间
get***KeySerializer()返回指定类别(字符串、list、map、set、zset、坐标)使用的序列化器
hasKey判断键是否存在
isExposeConnection返回是否公开连接代理(默认值)
keys根据匹配模式获得给定的键
killClient关闭指定连接
move将指定键移动到指定索引的数据源
multi标记事务
opsFor***返回(字符串、list、map、set、zset、坐标,集群)操作接口
persist移除过期key
randomKey获得一个随机key
rename给key进行重命名
renameIfAbsent当新的名称不存在时候进行重命名
restore还原操作
setBeanClassLoader设置类加载器
setDefaultSerializer设置默认序列化器
setExposeConnection设置是否将Redis连接公开到RedisCallback代码
set***Serializer设置指定类别(字符串、list、map、set、zset、坐标)使用的序列化器
slaveOf将redis复制设置更改为new master
slaveOfNoOne切换服务器为master
sort为指定结果排序
type返回键的类别
unlink断开键连接
unwatch刷新监控
watch在事务开始时使用RedisOperations.multi()监视给定的修改键
ValueOperations-操作字符串
方法描述
append向指定key中添加内容
bitField获得集合中复合 BitFieldSubCommands的结果
decrement将键中保存的整数减去指定值
get获得值
getAndSet设置参数并返回旧值
increment将键中保存的整数加去指定值
multiGet批量获得值
multiSet批量增加值
multiSetIfAbsent键不存在的时候设置值
set设置参数
setBit设置按键存储的值的偏移量
setIfAbsent如果key不存在则保存
setIfPresent如果key存在则保存
size获得指定结果的长度
HashOperations-操作hash
方法描述
delete删除map中指定值
entries获得map的entries
get获取map中的指定值
hasKey判断指定hasKey是否存在
increment给map中指定值增加值
keys返回map中key的集合
lengthOfValue返回map中指定值的长度
multiGet批量获得结果
put添加元素
putAll批量添加
putIfAbsent假如存在则添加
scan遍历集合
size获得指定键成员数量
values获得键结果的value集合
ListOperations-操作list
方法描述
index获得list指定元素的索引
leftPop删除并返回存储在键上的列表中的第一个元素
leftPush添加元素
leftPushAll批量添加元素
leftPushIfPresentlist存在则添加元素
range获得list中指定范围内容的元素
remove移除list指定的元素
rightPop删除并返回存储在键上的列表中的最后一个元素
rightPopAndLeftPush移除指定键最后一个元素,并添加至另外一个键的头部
rightPush添加元素
rightPushAll批量添加元素
rightPushIfPresentlist存在则添加元素
set在指定索引添加元素
size元素的总数量
trim剔除指定范围内的不合规元素
SetOperations-操作set
方法描述
add添加元素
difference获得两个键之间不同的内容
differenceAndStore获得集合中不同的内容,并且保存在新的键中
distinctRandomMembers从set中随机获取一定数量的结果
intersect合并键的元素
intersectAndStore合并键的元素并保存至指定键内
isMember判断指定键是否包含指定元素
members获取所有的元素
move将指定值从键1转移至键2
pop删除并返回一个随机元素
randomMember获取随机元素
randomMembers获取指定数量的随机元素
remove移除指定元素
scan遍历集合
size获得集合中元素数量
union合并两个集合
unionAndStore合并两个集合并保存在新的键中
ZSetOperations-操作ZSet(有序set)
方法描述
add添加或者更新元素
count指定范围内结果数量
incrementScore增加指定值的分数
intersectAndStore两个键联合排序,并保存在第三个键内
range获取指定范围的元素
rangeByLex获取指定范围的元素,条件为RedisZSetCommands.Range.getMin() and RedisZSetCommands.Range.getMax()
rangeByScore获取指定范围的元素,条件为分值
rangeByScoreWithScores获取指定范围的元素,条件为分值和索引
rangeWithScores获取指定范围之间的有序集合
rank获得指定元素的索引
remove移除指定的元素
removeRange移除此键对应集合中指定范围的元素
removeRangeByScore移除此键对应集合中指定分值范围的元素
reverseRange获取指定范围内的结合,排序从高到底
reverseRangeByScore获得set的RedisZSetCommands.Tuple从高到低,范围为选择的索引,
reverseRangeByScoreWithScores获得set的RedisZSetCommands.Tuple从高到低,范围为选择的索引,以及选择的分值
reverseRank当得分从高到低时,确定排序集合中指定元素的索引。
scan便利ZSet
score获取指定键,指定元素的分值
size获取指定键中元素的数量
unionAndStore将选择的两个键进行联合排序,并将结果保存在第三个键中
zCard获得指定key结果长度.
GeoOperations-操作Geo(地图信息)
方法描述
and添加坐标到指定键
distance计算两个坐标之间的距离
hash获得指定键,与之匹配的结果的Geohash显示
position获得指定键,与之匹配的结果的Point显示
radius获得指定坐标一定范围内的结果
remove移除坐标
HyperLogLogOperations-操作HyperLogLog(HyperLogLog算法)
方法描述
add添加值到指定键中
delete移除指定键
size获取指定键中元素的数量
union将指定键的所有值合并到目标键中.
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值