RedisTemplate位于spring-data-redis包下。RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅。
一、Redis的五种类型常用操作:使用RedisTemeplate
在maven中添加依赖(下面只是主要的部分依赖)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
RedisTemplate对五种类型的操作方式如下:
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
或者使用下面的方式
redistempalate.boundValueOps
redistempalate.boundSetOps
redistempalate.boundListOps
redistempalate.boundHashOps
redistempalate.boundZSetOps
opsForXXX和boundXXXOps的区别?
前者获取一个operator,但是没有指定操作的对象(key),可以在一个连接(事务)内操作多个key以及对应的value;后者获取了一个指定操作对象(key)的operator,在一个连接(事务)内只能操作这个key对应的value。
1、Value(值)类型
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testValue(){
redisTemplate.boundValueOps("testValue1").set("value1",60,TimeUnit.SECONDS); //设置过期时间为60秒,60秒后自动删除
redisTemplate.boundValueOps("testValue2").set("value2");
// redisTemplate.boundValueOps("testValue2").set("22222",3); //把testValue2的前三位置换为22222
}
@Test
public void getValue(){
Object o1 = redisTemplate.boundValueOps("testValue1").get();
Object o2 = redisTemplate.boundValueOps("testValue2").get();
System.out.println(o1 + " " + o2);
}
}
结果打印:value1、value2
可以使用redisTemplate.delete("testValue2");
进行删除操作
2、list类型
@Test
public void listTest(){
redisTemplate.boundListOps("list").leftPush("aaa");
redisTemplate.boundListOps("list").leftPush("aaa");
redisTemplate.boundListOps("list").leftPush("aaa");
redisTemplate.boundListOps("list").leftPush("bbb");
redisTemplate.boundListOps("list").rightPush("ccc");
redisTemplate.boundListOps("list").rightPush("ddd");
}
@Test
public void getList(){
List list = redisTemplate.boundListOps("list").range(0,10); //查询,range(0,10)会查询出0-10的元素
System.out.println(list);
System.out.println(redisTemplate.boundValueOps("list").getKey()); //获取key值
redisTemplate.boundListOps("list").remove(2,"aaa"); //删除两个个aaa
List list1 = redisTemplate.boundListOps("list").range(0,10); //查询,range(0,10)会查询出0-10的元素
System.out.println(list1);
redisTemplate.boundListOps("list").expire(60,TimeUnit.SECONDS); //设置60秒后过期
System.out.println(redisTemplate.boundListOps("list").index(1)); //根据索引获取值
System.out.println(redisTemplate.boundListOps("list").leftPop()); //bbb,打印左边起第一个元素值
}
3、set类型:无序、不可重复
@Test
public void setTest(){
redisTemplate.boundSetOps("set").add("aaa");
redisTemplate.boundSetOps("set").add("bbb");
redisTemplate.boundSetOps("set").add("ccc");
redisTemplate.boundSetOps("set").add("ddd");
}
@Test
public void getTest(){
Set set = redisTemplate.boundSetOps("set").members();
System.out.println(set); //[bbb, ccc, aaa, ddd]
redisTemplate.boundSetOps("set").remove("aaa");//删除aaa这个元素
redisTemplate.delete("set"); //删除整个集合
}
4、ZSet
@Test
public void zsetTest(){
redisTemplate.boundZSetOps("zset").add("aaa",1);
redisTemplate.boundZSetOps("zset").add("bbb",2);
redisTemplate.boundZSetOps("zset").add("ccc",3);
redisTemplate.boundZSetOps("zset").add("ddd",4);
}
@Test
public void getTest(){
Set zset = redisTemplate.boundZSetOps("zset").range(0,10);
System.out.println(zset); //[aaa, bbb, ccc, ddd]
redisTemplate.boundZSetOps("zset").removeRange(0,2); //删除0-2的元素,共三个
Set zset1 = redisTemplate.boundZSetOps("zset").range(0,10);
System.out.println(zset1); //[ddd]
}
5、hash类型
@Test
public void hashTest(){
redisTemplate.boundHashOps("hash").put("1", "a");
redisTemplate.boundHashOps("hash").put("2", "b");
redisTemplate.boundHashOps("hash").put("3", "c");
redisTemplate.boundHashOps("hash").put("4", "d");
}
@Test
public void getHashTest(){
List hash = redisTemplate.boundHashOps("hash").values();
System.out.println(hash);
Set set = redisTemplate.boundHashOps("hash").keys();
System.out.println(set);
Object o = redisTemplate.boundHashOps("hash").get("1");
System.out.println(o);
/**
* [a, b, c, d]
* [1, 2, 3, 4]
* a
*/
}
推荐阅读:使用RedisTemplate操作Redis数据库
注意:上面五种类型都可以使用redisTemeplate的expire(long l,TimeUnit timeUnit)函数设置过期时间。
TimeUnit有时分秒天等,如下图所示
二、RedisTemplate和StringRedisTemplate的区别
1、StringRedisTemplate继承RedisTemplate;
2、两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据
3、序列化方式不同
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的;
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
RedisTemplate使用的序列类在在操作数据的时候,比如说存入数据会将数据先序列化成字节数组然后在存入Redis数据库,这个时候打开Redis查看的时候,你会看到你的数据不是以可读的形式展现的,而是以字节数组显示,类似下面
当然从Redis获取数据的时候也会默认将数据当做字节数组转化,这样就会导致一个问题,当需要获取的数据不是以字节数组存在redis当中而是正常的可读的字符串的时候,比如说下面这种形式的数据
RedisTemplate就无法获取导数据,这个时候获取到的值就是NULL。这个时候StringRedisTempate就派上了用场。
当Redis当中的数据值是以可读的形式显示出来的时候,只能使用StringRedisTemplate才能获取到里面的数据。
所以当你使用RedisTemplate获取不到数据的时候请检查一下是不是Redis里面的数据是可读形式而非字节数组
对上面的进行测试也可得到答案
@Test
public void getTest1(){
System.out.println(redisTemplate.boundValueOps("test").get());
System.out.println(stringRedisTemplate.boundValueOps("test").get());
}
结果:
参考文章:RedisTemplate和StringRedisTemplate的区别