目录
二、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