RedisTemplate现在作为使用率最高的redis三方类库,隶属Spring技术栈,此篇文章意在指引RedisTemplate的快速上手。
在实践前,请确保已经有一个可连接的Redis服务。
科普:Redis的数据类型
Redis有五大基本数据类型:string、hash、list、set和zset。
string即是最单纯的k-v存储方式,使用set、get等指令。
hash是哈希表的存储方式,比较适合用来存储对象,每一条value相当于Java的一个Map,使用hmset、hget等指令。
list是简单的有序列表,每一条value相当于Java的一个List,使用lpush、lpop、rpush、rpop等指令。
set是哈希表实现的无序集合,每一条value相当于Java的一个Set,使用sadd、spop等指令。
zset是有序集合,每一条value相当于Java的一个LinkedHashSet。
step1:依赖库和基本参数配置
通过Maven引入spring-data-redis依赖(这里我们选择了依赖Springboo择相应的starter):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.0.0.RELEASE</version> </dependency>
引入相关的配置:
application.yml
spring: redis: password: xxx host: 10.0.0.1 database: 0 port: 6379 timeout: 1000ms jedis: pool: max-active: 100 #最大连接数 max-idle: 100 #最大空闲连接 max-wait: -1ms #阻塞等待时间 min-idle: 10
有关手动配置和更多的参数配置请参考博客[Quick Start]RedisTemplate的bean手动配置 -鱼鱼的Java小站
step2:RedisTemplate与StringRedisTemplate序列化碎碎念
这里准确的说是选择序列化和反序列化的方式,如无特殊需求,这两个类就可以满足与我们的存储要求。我们可以选择RedisTemplate与StringRedisTemplate,StringRedisTemplate是由RedisTemplate继承而来。不同于RedisTemplate默认的基于对象二进制序列化,其提供了基于字符串的键值序列化,即使用StringRedisTemplate存储的数据键值未经过特殊序列化,我们可以直接通过命令行查找redis获取相应的数据。相反地,使用RedisTemplate存储的数据即使是字符串,可能也无法直接解析出其内容。
而且不同序列化的Template类也不能通用,譬如利用默认RedisTemplate存入的key通常有诸如"\xAC\xED\x00\x05t"的前缀,不只是存取值,在使用keys()等方法匹配key的时候也会出问题,如果对于key值只存入String格式的数据,为了便于归类,我们也建议修改key的序列化方式为String,这样也便于查看:
redisTemplate.setKeySerializer(new StringRedisSerializer());
总结而言就是:数据庞大或是较为复杂的对象数据存储,使用RedisTemplate;源数据为体积较小的字符串的键值对,使用StringRedisTemplate。
当然,也可以手动指定序列化类,RedisTemplate的序列化类是JdkSerializationRedisSerializer,StringRedisTemplate使用的序列化类是StringRedisSerializer。
step3:使用配置好的RedisTemplate操作Redis-Java API
在StringBoot项目中可以直接使用Autowired注解注入相应的RedisTemplate对象使用,建议封装成工具类(手动配置)或是服务层(基于boot自动配置)。
RedisTemplate有两大类method API:boundXxxOps(key)和opsForXxx(),其中Xxx代表操作的数据类型,分别对应着绑定key的操作和通用的数据操作,这两者拥有的大部分同名API(opsForXxx可能会有更多的API)在功能上没什么区别,只是前者预置参数,更为便捷,一般直接使用后者操作Redis。例如,下面的代码:
@Autowired StringRedisTemplate stringRedisTemplate; //... //以下两行代码在功能上是一致的,不过考虑业务复杂性,一般使用opsForValue() stringRedisTemplate.boundValueOps("a:b:c").set("value4"); stringRedisTemplate.opsForValue().set("a:b:c","value4");
在这里列举出一些常用的API,统一使用opsForAPI。
注意:setIfAbsent可以直接设置超时时间的方法是在spring-data-redis 2.1.0.RELEASE 版本及之后才有的,建议使用这之后的方法,因为此方法用处很大(例如后文提到的分布式锁),而spring-boot提供的starter目前还没有超过此版本的依赖,所以若需要用到此方法,又不想手写配置的话,也可以覆盖依赖。
通用方法
//为k-v设置过期时间 redisTemplate.expire("key",30L,TimeUnit.MINUTES); //删除一个k-v,也可以传入Collection批量删除 redisTemplate.delete("key"); //获取某k-v过期时间 redisTemplate.getExpire("key"); //查看是否存在key redisTemplate.hasKey("key"); //按格式查找匹配的key,返回一个Set redisStringRedisTemplate.keys("*k*y*"));
value操作
//存入user对象 redisTemplate.opsForValue().set("key",user); //等同于setnx,若为空,则存入并返回true,设置过期值,反之维持原状并返回false,也有其他种参数列表 redisTemplate.opsForValue().setIfAbsent("key",user,30L,TimeUnit.MINUTES); //如果key对应的数据存在并且value值不为此次设置的值(user),则设置其值为user并返回true,反之维持原状并返回false //功能上可以说与setIfAbsent相反,有着与setIfAbsent相同的方法参数列表 redisTemplate.opsForValue().setIfPresent("key",user,30L,TimeUnit.MINUTES); //为某value为数字类型的数据做增加(increment)或减少(decrement)操作,第二个参数可以传double或long,,也可以不传为默认的1,会返回改变后的数值,数据格式错误会报错 redisTemplate.opsForValue().increment("num",10L); redisTemplate.opsForValue().decrement("num",2.1); //同时set多个值 redisTemplate.opsForValue().multiSet(map); //返回数据的value字符串长度 redisTemplate.opsForValue().size("key");
//TODO
有兴趣可以参考java-data-redis的Javadoc