• Redis学习(十)RedisTemplate 对各种数据类型的支持


    一、SpringDataRedis 简介

    1.1 什么是 Redis?

    Redis 是一款开源的 Key-Value 数据库,运行在内存中,由 C 语言编写。企业卡法通常采用 Redis 来实现缓存。同类的产品还有 Memecache、Memcached 等。

    1.2 什么是 Jedis

    Jedis 是 Redis 官方推出的一款面向 Java 的客户端,提供了很多接口供 Java 语言调用。可以在 Redis 官网下载,当然还有一些开源爱好者提供的客户端,如:Jredis、SRP 等等,推荐使用 Jedis。

    1.3 什么是 Spring Data Redis?

    spring-data-redis 是 Spring 大家族的一部分,提供了在 Spring 应用中通过简单的配置访问 Redis 服务,对 Redis 底层开发包(Jedis、JRedis、RJC)进行了高度封装,RedisTemplate 提供了 Redis 各种数据操作、异常处理及序列化、支持发布订阅,并对 Spring 3.1 Cache 进行了实现。

    spring-data-redis 提供功能如下:

    1. 连接池自动管理,提供了一个高度封装的 “RedisTemplate” 类。
    2. 针对 Jedis 客户端中大量 API 进行了归类封装,将同一类型操作封装为 Operation 接口:
      • ValueOperations: 简单 K-V 操作;
      • SetOperation: Set 类型数据操作;
      • ZSetOperations: ZSet 类型数据操作;
      • HashOperations: Map 类型的数据操作;
      • ListOperations: List 类型的数据操作。
    3. 提供了对 Key 的 “Bound” 便捷化操作 API,可以通过 Bound 封装指定的 Key,然后进行一系列的操作而无须 “显式” 的再次指定 Key,即 BoundKeyOperation:
      • BoundValueOperations
      • BoundListOperations
      • BoundHashOperations
      • BoundSetOperations
      • BoundZSetOperations

    在这里插入图片描述

    1. 将事务操作封装,有容器控制。
    2. 针对数据的 “序列化/反序列化”,提供了多种可选择策略(RedisSerializer)。
      • JdkSerializationRedisSerializer:POJO 对象的存取场景。使用 JDK 本身序列化机制,将 POJO 类通过 ObjectInputStream/ObjectOutputStream 进行序列化操作,最终 redis-server 中将存储字节序列化。这是目前最常用的序列化策略。
      • StringRedisSerializer:Key 或者 Value 为字符串的场景。根据指定的 charset 对数据的字节序列编码成 String,是 “new String(bytes, charset)” 和 “string.getBytes(charset)” 的直接封装。是最轻量级和高效的策略。
      • JacksonJsonRedisSerializer:jackson-json 工具提供了 JavaBean 与 JSON 之间的转换能力,可以将 POJO 实例序列化成 JSON 格式存储在 Redis 中,也可以将 JSON 格式的数据转换成 POJO 实例。因为 jackson 工具在序列化和反序列化时,需要明确指定 Class 类型,所以此策略封装起来稍微复杂。【需要 jackson-mapper-asl 工具支持】

    二、RedisTemplate 中 API 使用

    2.1 pom.xml 依赖

    
    <dependency>
    	<groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-redisartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.2 配置文件

    # Redis服务器连接端口
    spring.redis.port=6379
    # Redis服务器地址
    spring.redis.host=127.0.0.1
    # Redis数据库索引(默认为0)
    spring.redis.database=0
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接池最大连接数(适用负值表示没有限制)
    spring.redis.jedis.pool.max-active=8
    # 连接池最大阻塞等待时间(使用负值标识没有限制)
    spring.redis-jedis.pool.max-wait=-1ms
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    # 连接超时时间(毫秒)
    spring.redis.timeout=5000ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.3 RedisTemplate 的直接方法

    @Autowired
    private RedisTemplate redisTemplate;
    
    // 删除单个key
    redisTemplate.delete("keyTest");
    
    // 删除多个key
    redisTemplate.deleteKey("keyTest1", "keyTest2");
    
    // 指定key的失效时间
    redisTemplate.expire("keyTest", 1, TimeUnit.SECONDS);
    
    // 根据key获取过期时间
    long expire  = redisTemplate.getExpire("keyTest");
    
    // 判断key是否存在
    boolean hasKey = redisTemplate.hasKey("keyTest");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.4 String 类型相关操作

    @Autowired
    private RedisTemplate redisTemplate;
    
    // 添加缓存(通过 BoundValueOperations 设置值)
    redisTemplate.boundValueOps("KeyTest").set("ValueTest");
    redisTemplate.boundValueOps("KeyTest").set("ValueTest", 1, TimeUnit.SECONDS);
    // 添加缓存(通过 ValueOperations 设置值)
    redisTemplate.opsForValue().set("KeyTest", "ValueTest");
    redisTemplate.opsForValue().set("KeyTest", "ValueTest", 1, TimeUnit.SECONDS);
    
    // 设置过期时间(单独设置)
    redisTemplate.boundValueOps("KeyTest").expire(1, TimeUnit.SECONDS);
    redisTemplate.expire("KeyTest", 1, TimeUnit.SECONDS);
    
    // 获取缓存(通过 BoundValueOperations/ValueOperations 获取值)
    String valueTest = redisTemplate.boundValueOps("KeyTest").get();
    String valueTest = redisTemplate.opsForValue().get("KeyTest");
    
    // 删除缓存
    Boolean result = redisTemplate.delete("KeyTest");
    
    // 顺序递增
    redisTemplate.boundValueOps("KeyTest").increment(1L);
    
    // 顺序递减
    redisTemplate.boundValueOps("KeyTest").increment(-1L);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.5 Hash 类型相关操作

    // 添加缓存(通过 BoundHashOperations/HashOperations 设置值)
    redisTemplate.boundHashOps("KeyTest").put("name", "ACGkaka");
    redisTemplate.opsForHash().put("KeyTest", "name", "ACGkaka");
    
    // 设置过期时间(单独设置)
    redisTemplate.boundValueOps("KeyTest").expire(1, TimeUnit.SECONDS);
    redisTemplate.expire("KeyTest", 1, TimeUnit.SECONDS);
    
    // 添加一个Map集合
    HashMap<String, String> map = new HashMap<>();
    redisTemplate.boundHashOps("KeyTest").putAll(map);
    
    // 获取对象的所有属性key
    Set keys = redisTemplate.boundHashOps("KeyTest").keys();
    Set keys = redisTemplate.opsForHash().keys("KeyTest");
    
    // 获取对象的所有属性value
    List values = redisTemplate.boundHashOps("KeyTest").values();
    List values = redisTemplate.opsForHash().values("KeyTest");
    
    // 根据对象的属性key,获取属性value
    String value = (String) redisTemplate.boundHashOps("KeyTest").get("name");
    String value = (String) redisTemplate.opsForHash().get("KeyTest", "name");
    
    // 获取对象的所有属性键值对集合
    Map entries = redisTmpelate.boundHashOps("KeyTest").entries();
    Map entries = redisTemplate.opsForHash().entries("KeyTest");
    
    // 删除对象
    redisTemplate.delete("KeyTest");
    
    // 删除对象属性
    redisTemplate.boundHashOps("KeyTest").delete("name");
    
    // 判断对象是否存在
    Boolean isEmpty = redisTemplate.boundHashOps("KeyTest").hasKey("name");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    2.6 Set 类型相关操作

    // 添加缓存(通过 BoundHashOperations/HashOperations 设置值)
    redisTemplate.boundSetOps("KeyTest").add("ValueTest1", "ValueTest2");
    redisTemplate.opsForSet().add("KeyTest", "ValueTest1", "ValueTest2");
    
    // 设置过期时间(单独设置)
    redisTemplate.boundValueOps("KeyTest").expire(1, TimeUnit.SECONDS);
    redisTemplate.expire("KeyTest", 1, TimeUnit.SECONDS);
    
    // 根据key,获取Set中的所有值
    Set set = redisTemplate.boundSetOps("KeyTest").members();
    Set set = redisTemplate.opsForSet().members("KeyTest");
    
    // 根据value,从Set中查询是否存在
    Boolean isEmpty = redisTemplate.boundSetOps("KeyTest").isMember("ValueTest");
    
    // 获取Set缓存长度
    Long size = redisTemplate.boundSetOps("KeyTest").size();
    
    // 移除指定的单元
    Long result = redisTemplate.boundSetOps("KeyTest").remove("ValueTest");
    
    // 移除指定的key
    Boolean result = redisTemplate.delete("KeyTest");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.7 List 类型相关操作

    // 添加缓存(通过 BoundHashOperations 设置值)
    redisTemplate.boundListOps("KeyTest").leftPush("ValueTest");
    redisTemplate.boundListOps("KeyTest").rightPush("ValueTest");
    // 添加缓存(通过 HashOperations 设置值)
    redisTemplate.opsForList().leftPush("KeyTest", "ValueTest");
    redisTemplate.opsForList().rightPush("KeyTest", "ValueTest");
    
    // 设置过期时间
    redisTemplate.boundValueOps("KeyTest").expire(1, TimeUnit.SECONDS);
    redisTemplate.expire("KeyTest", 1, TimeUnit.SECONDS);
    
    // 添加一个List集合
    List<String> list = new ArrayList<>();
    redisTemplate.boundListOps("KeyTest").leftPushAll(list);
    redisTemplate.boundListOps("KeyTest").rightPushAll(list);
    
    // 根据索引,获取一段缓存
    List list = redisTemplate.boundListOps("KeyTest").range(0, 10);
    
    // 从左弹出一个元素
    String key = (String) redisTemplate.boundListOps("KeyTest").leftPop();
    
    // 从右弹出一个元素
    String key = (String) redisTemplate.boundListOps("KeyTest").rightPop();
    
    // 根据索引,查询元素
    String key = (String) redisTemplate.boundListOps("KeyTest").index(1);
    
    // 获取List缓存的长度
    Long size = redisTemplate.boundListOps("KeyTest").size();
    
    // 根据索引,修改List中的某条数据
    redisTemplate.boundListOps("KeyTest").set(3L, "ValueTest");
    
    // 移除N个value值
    redisTemplate.boundListOps("KeyTest").remove(3L, "ValueTest");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    2.8 ZSet 类型相关操作

    zset中value不允许重复,默认升序排序。

    // 添加缓存(通过 BoundHashOperations 设置值)
    redisTemplate.boundZSetOps("KeyTest").add("ValueTest", 10D);
    // 添加缓存(通过 HashOperations 设置值)
    redisTemplate.opsForZSet().add("KeyTest", "ValueTest", 10D);
    
    // 添加多个缓存
    DefaultTypedTuple<String> p1 = new DefaultTypedTuple<>("ValueTest", 1.1D);
    DefaultTypedTuple<String> p2 = new DefaultTypedTuple<>("ValueTest", 1.2D);
    redisTemplate.boundZSetOps("KeyTest").add(new HashSet<>(Arrays.asList(p1, p2)));
    
    // 按照排名先后(从小到大)打印指定区间内的元素,-1为打印全部
    Set<String> range = redisTemplate.boundZSetOps("KeyTest").range(0, -1);
    
    // 获取指定元素的分数
    Double score = redisTemplate.boundZSetOps("KeyTest").score("VelueTest");
    
    // 获取元素个数
    Long size = redisTemplate.boundZSetOps("KeyTest").size();
    
    // 获取分数范围内的元素个数
    Long count = redisTemplate.boundZSetOps("KeyTest").count(0D, 2.2D);
    
    // 获取分数范围内的元素
    Set set = redisTemplate.boundZSetOps("KeyTest").rangeByScore(0D, 2.2D);
    
    // 获取分数范围内的元素,带偏移量和个数(key, 起始分数, 最大分数, 偏移量, 个数)
    Set set = redisTemplate.opsForZSetOps().rangeByScore("KeyTest", 0D, 2.2D, 1, 3);
    
    // 获取分数范围内元素的排名及分数
    Set<TypedTuple<String>> tuples = redisTemplate.boundZSetOps("KeyTest").rangeWithScores(0L, 3L);
    for (TypedTuple<String> tuple : tuples) {
        System.out.println(tuple.getValue() + ":" + tuple.getScore());
    }
    
    // 获取排名(从小到大)
    Long rank = redisTemplate.boundZSetOps("KeyTest").rank("ValueSet");
    
    // 获取排名(从大到小)
    Long reverseRank = redisTemplate.boundZSetOps("KeyTest").reverseRank("ValueSet");
    
    // 根据value删除元素
    redisTemplate.boundZSetOps("KeyTest").remove("ValueSet");
    
    // 根据索引范围删除元素
    redisTemplate.boundZSetOps("KeyTest").removeRange(0L, 3L);
    
    // 根据分数范围删除元素
    redisTemplate.boundZSetOps("KeyTest").removeRangeByScore(0D, 2.2D);
    
    // 根据value为元素加分
    Double score = redisTemplate.boundZSetOps("KeyTest").incrementScore("ValueTest", 1.1D);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    整理完毕,完结撒花~ 🌻





    参考地址:

    1.RedisTemplate操作Redis,这一篇文章就够了(一),https://blog.csdn.net/lydms/article/details/105224210

    2.Springboot使用RedisTemplate优雅地操作redis,https://zhuanlan.zhihu.com/p/69103214

  • 相关阅读:
    【深入浅出Spring6】第一期——入门
    Day 78
    python 笔记:h5py 读取HDF5文件
    开源供应链管理系统 多供应商批发管理系统方案及源码输出
    【BOOST C++ 15 泛型编程】(1)Boost.TypeTraits
    kafka可视化工具Kafka Tool安装使用
    【SUMO】初级 Public Transport - 1
    JupyterLab使用指南(四):JupyterLab的Magic 命令
    解决:使用WileyNJDv5_Template模板时,无法生成pdf文件。
    DataFrame创建介绍_大数据培训
  • 原文地址:https://blog.csdn.net/qq_33204709/article/details/134246204