RedisTemplate用法学习

目录

一、spring-data-redis功能介绍

二、Spring-data-redis中对String数据结构的操作

三、Spring-data-redis中对List数据结构的操作

四、Spring-data-redis中对Hash数据结构的操作

五、Spring-data-redis中对Set数据结构的操作

六、Spring-data-redis中对Zset数据结构的操作


Redis可以存储五种不同类型的数据结构,这五种数据结构分别为:
  String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。
Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis,  JRedis, and RJC)进行了高度封装。RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。
spring-data-redis官网:http://projects.spring.io/spring-data-redis
git项目地址:https://github.com/spring-projects/spring-data-redis

一、spring-data-redis功能介绍

jedis客户端在编程实施方面存在如下不足:

1) connection管理缺乏自动化,connection-pool的设计缺少必要的容器支持。
2) 数据操作需要关注“序列化”/“反序列化”。因为jedis的客户端API接受的数据类型为string和byte,对结构化数据(json,xml,pojo等)操作需要额外的支持。
3) 事务操作纯粹为硬编码。
4) 对于pub/sub功能,缺乏必要的设计模式支持。对于开发者而言,需要关注的太多。
针对jedis的不足,spring-data-redis提供了如下功能:

1. 连接池自动管理,提供了一个高度封装的RedisTemplate类

2. 对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口operation接口类型有如下几类:

  ValueOperations:简单K-V操作

  SetOperations:set类型数据操作

  ZSetOperations:zset类型数据操作

  HashOperations:针对map类型的数据操作

  ListOperations:针对list类型的数据操作

3. 提供了对key的bound(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作,而无须“显式”地再次指定Key。BoundKeyOperations有如下几类:

   BoundValueOperations

   BoundSetOperations

   BoundListOperations

   BoundSetOperations

  BoundHashOperations

4. 将事务操作封装,有容器控制。


5. 针对数据的“序列化/反序列化”,提供了多种可选择策略(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工具支持】。


OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb、apache-xmlbeans,redis存储的数据将是xml类型。使用此策略,编程将会有些难度,而且效率最低,不建议使用【需要spring-oxm模块的支持】。


         对于“序列化和反序列化”,JdkSerializationRedisSerializer和StringRedisSerializer是最基础的策略。原则上,我们可以将数据存储为任何格式,以便应用程序存取和解析(其中应用包括app、hadoop等其他工具),但是在设计时仍然不推荐直接使用“JacksonJsonRedisSerializer”和“OxmSerializer”。因为无论是json还是xml,他们本身仍然是String。如果你的数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer,而不是JdkSerializationRedisSerializer。如果你的数据格式必须为json或者xml,那么在编程级别,在redisTemplate配置中仍然使用StringRedisSerializer,在存储之前或者读取之后,使用“SerializationUtils”工具转换转换成json或者xml即可。

 

6.基于设计模式和JMS开发思路,将pub/sub的API设计进行了封装,使开发更加便捷。


7. 在spring-data-redis中,并没有对sharding提供良好的封装。如果你的架构是基于sharding,那么你需要自己去实现,这也是sdr和jedis相比,唯一缺少的特性。

 

二、Spring-data-redis中对String数据结构的操作

1.  set void set(K key, V value);

redisTemplate.opsForValue().set("num","123");
redisTemplate.opsForValue().get("num")  
//输出为:123

2. set void set(K key, V value, long timeout, TimeUnit unit); 

redisTemplate.opsForValue().set("num","123",10, TimeUnit.SECONDS);
redisTemplate.opsForValue().get("num") 
//设置为10秒失效,10之内查询有结果,十秒之后返回为null

时间单位为:

TimeUnit.DAYS          //天
TimeUnit.HOURS         //小时
TimeUnit.MINUTES       //分钟
TimeUnit.SECONDS       //秒
TimeUnit.MILLISECONDS  //毫秒 

3. set void set(K key, V value, long offset)

覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。

template.opsForValue().set("key","hello world");
template.opsForValue().set("key","redis", 6);
System.out.println("***************"+template.opsForValue().get("key"));
//输出为:***************hello redis

 4.g et V get(Object key)

获取指定key对应的value。

template.opsForValue().set("key","hello world");
System.out.println("***************"+template.opsForValue().get("key"));
//输出为:***************hello world

5. getAndSet(K key, V value)

设置键的字符串值,并返回其旧值。

template.opsForValue().set("getSetTest","test");
System.out.println(template.opsForValue().getAndSet("getSetTest","test2"));
//输出为:test

6. append(K key, String value)

如果key已经存在,并且是一个字符串,则该命令将该值追加到字符串的末尾。如果键不存在,则它被创建,并设置为空字符串。因此,APPEND在这种特殊情况下将类似于SET。

template.opsForValue().append("test","Hello");
System.out.println(template.opsForValue().get("test"));
template.opsForValue().append("test","world");
System.out.println(template.opsForValue().get("test"));
//输出结果为:
//Hello
//Helloworld

7. size Long size(K key);
返回key所对应value值的长度。

template.opsForValue().set("key","hello world");
System.out.println("***************"+template.opsForValue().size("key"));
//输出为:***************11

三、Spring-data-redis中对List数据结构的操作

1. Long size(K key)
返回存储在键中的列表的长度。如果键不存在,则将其解释为空列表,并返回0。当key存储的值不是列表时,返回错误。

System.out.println(template.opsForList().size("list"));
输出为:6

2. Long leftPush(K key, V value)
将指定的值插入到列表的头部。如果键不存在,则在执行推送操作之前,将其创建为空列表(从左边插入)。

template.opsForList().leftPush("list","java");
template.opsForList().leftPush("list","python");
template.opsForList().leftPush("list","c++");
//返回的结果为推送操作后的列表的长度
//1
//2
//3

3. Long leftPushAll(K key, V... values)
批量把一个数组插入到列表中(从左边插入)。

String[] strs = new String[]{"1","2","3"};
template.opsForList().leftPushAll("list",strs);
System.out.println(template.opsForList().range("list",0,-1));
//输出为: [3, 2, 1]

4. Long rightPush(K key, V value)
将指定的值插入到列表的头部。如果键不存在,则在执行推送操作之前,将其创建为空列表(从右边插入)。

template.opsForList().rightPush("listRight","java");
template.opsForList().rightPush("listRight","python");
template.opsForList().rightPush("listRight","c++");
//结果为:
//1
//2
//3

5. Long rightPushAll(K key, V... values)

批量把一个数组插入到列表中(从右边插入)。

String[] strs = new String[]{"1","2","3"};
template.opsForList().rightPushAll("list",strs);
System.out.println(template.opsForList().range("list",0,-1));
//输出为:[1, 2, 3]

6. void set(K key, long index, V value)
在列表的index位置,设置value值。

System.out.println(template.opsForList().range("listRight",0,-1));
template.opsForList().set("listRight",1,"setValue");
System.out.println(template.opsForList().range("listRight",0,-1));
//输出为
//[java, python, oc, c++]
//[java, setValue, oc, c++]

7. Long remove(K key, long count, Object value)
从列表中删除等于值的元素的第一个计数事件。
计数参数以下列方式影响操作:
count> 0:删除等于从头到尾移动的值的元素。
count <0:删除等于从尾到头移动的值的元素。
count = 0:删除等于value的所有元素。
 

System.out.println(template.opsForList().range("listRight",0,-1));
template.opsForList().remove("listRight",1,"setValue");
//将删除列表中第一次出现的“setValue”。
System.out.println(template.opsForList().range("listRight",0,-1));
//输出如下
//[java, setValue, oc, c++]
//[java, oc, c++]

8. V index(K key, long index)
根据下标获取列表中的值,下标是从0开始的。

System.out.println(template.opsForList().range("listRight",0,-1));
System.out.println(template.opsForList().index("listRight",2));
//输出为:
//[java, oc, c++]
//c++

9. V leftPop(K key)
弹出最左边的元素。在弹出之后,该值在列表中将不复存在。

System.out.println(template.opsForList().range("list",0,-1));
System.out.println(template.opsForList().leftPop("list"));
System.out.println(template.opsForList().range("list",0,-1));
//输出为
//[c++, python, oc, java, c#, c#]
//c++
//[python, oc, java, c#, c#]

10. V rightPop(K key)
弹出最右边的元素。在弹出之后,该值在列表中将不复存在。

System.out.println(template.opsForList().range("list",0,-1));
System.out.println(template.opsForList().rightPop("list"));
System.out.println(template.opsForList().range("list",0,-1));
//输出为
//[python, oc, java, c#, c#]
//c#
//[python, oc, java, c#]

四、Spring-data-redis中对Hash数据结构的操作

1. Long delete(H key, Object... hashKeys)
删除给定哈希的hashKeys。

System.out.println(template.opsForHash().delete("redisHash","name"));
System.out.println(template.opsForHash().entries("redisHash"));
//输出为
//1
//{class=6, age=28.1}

2. Boolean hasKey(H key, Object hashKey)
判断哈希的hashKey是否存在。

System.out.println(template.opsForHash().hasKey("redisHash","666"));
System.out.println(template.opsForHash().hasKey("redisHash","777"));
//输出为:
//true
//false

3. HV get(H key, Object hashKey)
从哈希中获取给定hashKey的值。

System.out.println(template.opsForHash().get("redisHash","age"));
//输出为:26

4.  Set<HK> keys(H key)
获取哈希表所有的hashKey。

System.out.println(template.opsForHash().keys("redisHash"));
//redisHash所对应的散列表为{class=1, name=666, age=27}
//输出为:[name, class, age]

5. Long size(H key)
获取哈希表的大小。

System.out.println(template.opsForHash().size("redisHash"));
//redisHash所对应的散列表为{class=1, name=666, age=27}
//输出为:3

6. void putAll(H key, Map<? extends HK, ? extends HV> m)
将“m中提供的多个散列字段”设置到“key对应的散列表”中。

Map<String,Object> testMap = new HashMap();
testMap.put("name","666");
testMap.put("age",27);
testMap.put("class","1");
template.opsForHash().putAll("redisHash1",testMap);
System.out.println(template.opsForHash().entries("redisHash1"));
//输出为:{class=1, name=jack, age=27}

7. void put(H key, HK hashKey, HV value)
设置散列hashKey的值。

template.opsForHash().put("redisHash","name","666");
template.opsForHash().put("redisHash","age",26);
template.opsForHash().put("redisHash","class","6");
System.out.println(template.opsForHash().entries("redisHash"));
//输出为:{age=26, class=6, name=666}

8. List<HV> values(H key)
获取整个哈希存储的值。

System.out.println(template.opsForHash().values("redisHash"));
//输出为:[tom, 26, 6]

9. Map<HK, HV> entries(H key)
获取哈希表存储的所有key和value。

System.out.println(template.opsForHash().entries("redisHash"));
//输出为:{age=26, class=6, name=tom}

10.  Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options);
使用Cursor在hash中迭代,相当于迭代器。

Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("redisHash", 
  ScanOptions.ScanOptions.NONE);
    while(curosr.hasNext()){
        Map.Entry<Object, Object> entry = curosr.next();
        System.out.println(entry.getKey()+":"+entry.getValue());
    }
//输出为
//age:27
//class:6
//name:666

五、Spring-data-redis中对Set数据结构的操作

1. Long add(K key, V... values)
无序集合中添加元素,返回添加个数。
也可以直接在add里面添加多个值, 如:template.opsForSet().add("setTest","aaa","bbb")

String[] strs= new String[]{"str1","str2"};
System.out.println(template.opsForSet().add("setTest", strs));
//输出为:2

2. Long remove(K key, Object... values);
移除集合中一个或多个成员。

String[] strs = new String[]{"str1","str2"};
System.out.println(template.opsForSet().remove("setTest",strs));
//输出为:2

3. V pop(K key)
移除并返回集合中的一个随机元素。

System.out.println(template.opsForSet().pop("setTest"));
System.out.println(template.opsForSet().members("setTest"));
//输出为
//bbb
//[aaa, ccc]

4. Boolean move(K key, V value, K destKey);
将member元素从source集合移动到destination集合。

template.opsForSet().move("setTest","aaa","setTest2");
System.out.println(template.opsForSet().members("setTest"));
System.out.println(template.opsForSet().members("setTest2"));
//输出为
//[ccc]
//[aaa]

5. Long size(K key)
获取无序集合的大小长度。

System.out.println(template.opsForSet().size("setTest"));
//输出为:1

6. Set<V> members(K key)
返回集合中的所有成员。

System.out.println(template.opsForSet().members("setTest"));
//输出为:[ddd, bbb, aaa, ccc]

7. Cursor<V> scan(K key, ScanOptions options);
使用Cursor遍历set集合,相当于迭代器。

Cursor<Object> curosr = template.opsForSet().scan("setTest", ScanOptions.NONE);
  while(curosr.hasNext()){
     System.out.println(curosr.next());
  }
//输出为:
//ddd
//bbb
//aaa
//ccc

六、Spring-data-redis中对Zset数据结构的操作

1. Boolean add(K key, V value, double score)
新增一个有序集合的元素,若已存在,则返回false;若不存在,则返回true。

System.out.println(template.opsForZSet().add("zset1","zset-1",1.0));
//输出为:true

2. Long add(K key, Set<TypedTuple<V>> tuples);
新增一个有序集合的元素。

ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<>("zset-5",9.6);
ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("zset-6",9.9);
Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
tuples.add(objectTypedTuple1);
tuples.add(objectTypedTuple2);
System.out.println(template.opsForZSet().add("zset1",tuples));
System.out.println(template.opsForZSet().range("zset1",0,-1));
//输出为
//true
//[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]

3. Long remove(K key, Object... values)
从有序集合中移除一个或者多个元素。

System.out.println(template.opsForZSet().range("zset1",0,-1));
System.out.println(template.opsForZSet().remove("zset1","zset-6"));
System.out.println(template.opsForZSet().range("zset1",0,-1));
//输出为:
//[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
//1
//[zset-1, zset-2, zset-3, zset-4, zset-5]

4. Long rank(K key, Object o)
返回有序集合中指定成员的排名,有序集合的成员按分数值递增(从小到大)顺序排列。

System.out.println(template.opsForZSet().range("zset1",0,-1));
System.out.println(template.opsForZSet().rank("zset1","zset-2"));
//输出为
//[zset-2, zset-1, zset-3, zset-4, zset-5]
//0   (说明:表明排名第一)

5. Set<V> range(K key, long start, long end)
通过索引区间返回有序集合指定区间内的成员,有序集成员按分数值递增(从小到大)顺序排列。

System.out.println(template.opsForZSet().range("zset1",0,-1));
//输出为
//[zset-2, zset-1, zset-3, zset-4, zset-5]

6. Long count(K key, double min, double max)
通过分数返回有序集合指定区间内的成员个数。

System.out.println(template.opsForZSet().rangeByScore("zset1",0,5));
System.out.println(template.opsForZSet().count("zset1",0,5));
//输出为
//[zset-2, zset-1, zset-3]
//3

7.  Long size(K key)
获取有序集合的成员数,内部调用的就是zCard方法。

System.out.println(template.opsForZSet().size("zset1"));
//输出为:6

8. Double score(K key, Object o)
获取指定成员的score值。

System.out.println(template.opsForZSet().score("zset1","zset-1"));
//输出为:2.2

9. Long removeRange(K key, long start, long end)
移除指定索引范围内的成员,有序集成员按分数值递增(从小到大)顺序排列。

System.out.println(template.opsForZSet().range("zset2",0,-1));
System.out.println(template.opsForZSet().removeRange("zset2",1,2));
System.out.println(template.opsForZSet().range("zset2",0,-1));
//输出为
//[zset-1, zset-2, zset-3, zset-4]
//2
//[zset-1, zset-4]

10. Cursor<TypedTuple<V>> scan(K key, ScanOptions options);
使用Cursor遍历zset,相当于迭代器。

Cursor<ZSetOperations.TypedTuple<Object>> cursor = template.opsForZSet().scan("zzset1", ScanOptions.NONE);
    while (cursor.hasNext()){
       ZSetOperations.TypedTuple<Object> item = cursor.next();
       System.out.println(item.getValue() + ":" + item.getScore());
    }
//输出为
//zset-1:1.0
//zset-2:2.0
//zset-3:3.0
//zset-4:6.0

参考:

https://blog.csdn.net/weixin_40461281/article/details/103416876

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值