SpringBoot中StringRedisTemplate与RedisTemplate区别,以及StringRedisTemplate操作String List队列 Hash Set 详解 模糊查询

目录


一、SpringBoot操作Redis主要有两种常用操作,如下:

StringRedisTemplateRedisTemplate

二、StringRedisTemplate与RedisTemplate区别:

•  两者的关系是StringRedisTemplate继承RedisTemplate。
•  两者的数据是不共通的;也就是说:
        StringRedisTemplate只能管理StringRedisTemplate里面的数据;
        RedisTemplate只能管理RedisTemplate中的数据。
•  其实他们两者之间的区别主要在于他们使用的序列化类:
        RedisTemplate使用的是JdkSerializationRedisSerializer  存入数据会将数据先序列化成字节数组然后在存入Redis数据库;
        StringRedisTemplate使用的是StringRedisSerializer。
•  使用时注意事项:
        当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可;
        但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。
•    RedisTemplate使用时常见问题:
        redisTemplate 中存取数据都是字节数组。当redis中存入的数据是可读形式而非字节数组时,使用redisTemplate取值的时候会无法获取导出数据,获得的值为null。可以使用 StringRedisTemplate 试试。


•    RedisTemplate中定义了5种数据结构操作:
        redisTemplate.opsForValue();  //操作字符串
        redisTemplate.opsForHash();  //操作hash
        redisTemplate.opsForList();     //操作list
        redisTemplate.opsForSet();     //操作set
        redisTemplate.opsForZSet();   //操作有序set        
 

三、本文以StringRedisTemplate为例:

1、POM依赖:

<!-- Radis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、Redis连接池配置:

(也可以不写以下配置项,将下载的redis设置在windows服务中,开机自启动)

# Redis
spring.redis.host=@spring.redis.host@
spring.redis.password=@spring.redis.password@
spring.redis.port=${port:6379}
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=1
# 连接超时时间(毫秒)
spring.redis.timeout=300

3、注入对象:

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

4、Redis 过期时间,模糊查询和通用操作:

	//向redis里存入数据和设置缓存时间(按指定时间单位)
	stringRedisTemplate.opsForValue().set("count","20",60*10,TimeUnit.SECONDS);

	//设置过期时间,//如果这个方法与上个方法同时使用,会刷新过期时间
	stringRedisTemplate.expire("count",1000,TimeUnit.SECONDS);
	
	//根据key获取过期时间,//返回的值是剩余的过期时间
	Long stringRedisTemplate.getExpire("count");

	//根据key获取过期时间(按指定时间单位返回),//返回的值是剩余的过期时间
	Long stringRedisTemplate.getExpire("count",TimeUnit.SECONDS);

	//根据key删除缓存
	stringRedisTemplate.delete("count");   // 返回boolean 
	
	//检查key是否存在
	stringRedisTemplate.hasKey("count");   // 返回boolean 

    //Redis模糊查找(不推荐使用,会全表扫描,影响性能)
    //Redis中keys命令进行获取key值,具体命令格式:keys pattern 
    //Redis中允许模糊查询的有3个通配符,分别是:*,?,[]
    // 其中:
    // *:通配任意多个字符
    stringRedisTemplate.keys("*" + pattern + "*");
    // ?:通配单个字符
    stringRedisTemplate.keys("?" + pattern);
    // []:通配括号内的某一个字符
    stringRedisTemplate.keys("[" + pattern + "]");
    

备注:使用RedisTemplate模糊查询,遇到问题key存在,而redisTemplate查找不到,如:“A_091_JPFX”,但是用 模糊key:“A_*_JPFX”匹配时,却匹配不到,是序列话编码问题导致(二中有描述),使用stringRedisTemplate即可。 

5、Redis String:

	//向redis存入数据
	stringRedisTemplate.opsForValue().set("key","50");
	
	//根据key获得缓存中的value(opsForValue().get("key"))
	stringRedisTemplate.opsForValue().get("key");//key:Object
	
	//value做-1操作
	stringRedisTemplate.boundValueOps("key").increment(-1);//-1:Long/Double
	
	//value做+1操作
	stringRedisTemplate.boundValueOps("key").increment(1);//1:Long/Double
		
	//根据key删除缓存
	stringRedisTemplate.delete("count");    // 返回boolean 
	
	//检查key是否存在
	stringRedisTemplate.hasKey("count");    // 返回boolean 

6、Redis List:

	// list数据类型适合于消息队列的场景:比如12306并发量太高,而同一时间段内只能处理指定数量的数据!
    // 必须满足先进先出的原则,其余数据处于等待
    // leftPush依次由右边添加
    Long stringRedisTemplate.opsForList().rightPush("redlist","1");
    Long stringRedisTemplate.opsForList().rightPush("redlist","2");
    Long stringRedisTemplate.opsForList().rightPush("redlist", "A");
    Long stringRedisTemplate.opsForList().rightPush("redlist", "B");
    
    // leftPush依次由左边添加
    Long stringRedisTemplate.opsForList().leftPush("redlist", "0");
    // 从左边批量插入新值
    List<String> strings = Arrays.asList("j", "q", "k");
    stringRedisTemplate.opsForList().leftPushAll("list", strings);

	// 查询类别所有元素
    List<String> listAll = stringRedisTemplate.opsForList().range( "redlist", 0, -1);//["0","1","2","A","B"]
    
    // 查询前2个元素
    List<String> list = stringRedisTemplate.opsForList().range( "redlist", 0, 1);//["0","1"]
	
	// 删除先进入的B元素(如果含有多个B元素,删除最左边的)
    Long stringRedisTemplate.opsForList().remove("redlist",1, "B");//["0","1","2","A"]
    
   	// 删除所有A元素
    Long stringRedisTemplate.opsForList().remove("redlist",0, "A");//["0","1","2"]	 
 扩展:队列处理
1、leftPush(K key, V value) 
// 从集合左边插入值
// 值重复无影响
// 先进先出
redisTemplate.opsForList().leftPush("list","a");
redisTemplate.opsForList().leftPush("list","a");
redisTemplate.opsForList().leftPush("list","b");

2、leftPush(K key, V v, V v1)
// 从集合左边开始在v值后边插入新值v1
// 在集合中查找v值
// 有多个v值时,从左边开始查到第一个v值即可(也就是最后插入的v值,靠左的v值),然后在v值左边插入新值v1
// 不存在v时,不插入新值v1
redisTemplate.opsForList().leftPush("list", "a", "e");

3、leftPushAll(K key, Collection values)
// 从左边批量插入新值
List<String> strings = Arrays.asList("j", "q", "k");
redisTemplate.opsForList().leftPushAll("list", strings);

4、leftPushAll(K key, V… values)
// 从左边批量插入新值(同上)
redisTemplate.opsForList().leftPushAll("list", "j", "q", "k");

5、leftPushIfPresent(K key, V value)
// 如果key存在,从左边插入新值
// key不存在,不新增
redisTemplate.opsForList().leftPushIfPresent("list", "j");

6、leftPop(K key)
// 默认移除key中最左的一个值
redisTemplate.opsForList().leftPop("list");

7、leftPop(K key, long timeout, TimeUnit unit)
// 指定过期时间后删除key中最左的一个值
redisTemplate.opsForList().leftPop("list",1,TimeUnit.MINUTES);

8、rightPopAndLeftPush(K k1, K k2)
// 移除k1中最右的值,并将移除的值插入k2中最左侧
// k1和k2不是同一个key时,k1右侧移除,k2左侧插入,k2不存在时则新增一个然后在插入
// k1和k2是同一个key时,相当于把最右侧的值移到了最左侧
redisTemplate.opsForList().rightPopAndLeftPush("list", "list2");

9、rightPopAndLeftPush(K k1, K k2, long timeout, TimeUnit unit)
// 指定过期时间后,移除k1中最右的值,并将移除的值插入k2中最左侧(同上)
// k1和k2不是同一个key时,k1右侧移除,k2左侧插入,k2不存在时则新增一个然后在插入
// k1和k2是同一个key时,相当于把最右侧的值移到了最左侧
redisTemplate.opsForList().rightPopAndLeftPush("list", "list2",1,TimeUnit.MINUTES);

10、rightPush(K key, V value)
// 从右侧插入新值
redisTemplate.opsForList().rightPush("rightList",'a');
redisTemplate.opsForList().rightPush("rightList",'b');
redisTemplate.opsForList().rightPush("rightList",'c');

11、rightPush(K key, V v1, V v2)
// 从右查找v1,并在v1右侧插入新值v2
// v1有多个,只找到最靠右的一个即可
// v1没有,不插入
redisTemplate.opsForList().rightPush("rightList", "b", "e");

12、rightPushAll(K key, V… values)
// 从右侧批量插入
redisTemplate.opsForList().rightPushAll("rightList", "e", "f","g");

13、rightPushAll(K key, Collection values)
// 从右侧批量插入
List<String> strings = Arrays.asList("j", "q", "k");
redisTemplate.opsForList().rightPushAll("rightList", strings);

14、rightPushIfPresent(K key, V value)
// 如果key存在,在右侧新插入value,否则不插入
redisTemplate.opsForList().rightPushIfPresent("rightList", "a");

15、rightPop(K key)
// 默认从最右侧移除一个值
redisTemplate.opsForList().rightPop("rightList");

16、rightPop(K key, long timeout, TimeUnit unit)
// 指定过期时间后,从最右侧移除一个值
redisTemplate.opsForList().rightPop("rightList",1,TimeUnit.MINUTES);

17、index(K key, final long index)
// 获取指定位置的值(index从左往右,从0开始)
// 超过下标,不报错,返回null
String string1 = (String) redisTemplate.opsForList().index("rightList", 2);
System.out.println("string1 = " + string1);

18、size(K key)
// 获取对应key的集合长度
Long size = redisTemplate.opsForList().size("rightList");
System.out.println("size = " + size);

19、set(K key, final long index, V value)
// 在指定坐标位置插入(替换)新值
// index不存在,报错(ERR index out of range)
// key不存在,报错(ERR no such key)
// 从左侧插入
redisTemplate.opsForList().set("rightList",2,"e");

20、trim(K key, long long1, long long2)
// 截取下标long1和long2之间的值,包括long1和long2对应的值,并将其保留为key对应的新值
// 左侧坐标从0开始,右侧从-1开始
// 当long1超过坐标时(此时与long2无关),都会截取为空,key会被删除
// 当long1为负时(此时与long2无关),都会截取为空,key会被删除
// 当long1为正且在下标存在其中,long2为负数时,只要两个没有重叠,相当于去左去右,保留了中间的部分
// 当long1为正且在下标存在其中,long2为负数时,只要两个交叉重叠,截取为空,如下图
redisTemplate.opsForList().trim("rightList",1,3);

21、List range(K key, long start, long end)
// 获取指定下标间的值
redisTemplate.opsForList().range("rightList", 0, -1);//获取所有值

22、remove(K key, long count, Object value)
// 从存储在键中的列表中删除等于值的元素的第一个计数事件。
count> 0:删除等于从左到右移动的值的第一个元素;
count< 0:删除等于从右到左移动的值的第一个元素;
count = 0:删除等于value的所有元素。
redisTemplate.opsForList().remove("rightList", 0, "c");

23、拓展
当存储对象、对象集合时,最好转为JSON字符串,方便存储解析

备注示例: leftPush(K key, V v, V v1)

7、Redis Hash:

	// map的key值相同,后添加的覆盖原有的(h,hk,hv)
    void stringRedisTemplate.opsForHash().put("redmap","a","b");
    void stringRedisTemplate.opsForHash().put("redmap","a","d");
    void stringRedisTemplate.opsForHash().put("redmap","b","d");
	 
    // 获取map对象
    Map<Object, Object> map = stringRedisTemplate.opsForHash().entries("redmap");//{"a":"d","b":"d"}
	
	// 根据map的key删除这个元素 
    //第二个参数是不定长的,可以写多个,例如:delete("redmap","c","d"),当删除完所有的key时,该map对象注销
    Long stringRedisTemplate.opsForHash().delete("redmap", "c"); 
	
	// 获得map的key集合
    Set<Object> objects =  stringRedisTemplate.opsForHash().keys("redmap");//["a","b"]
	 
	// 获得map的value列表
    List<Object> objects = stringRedisTemplate.opsForHash().values("redmap");//["d","d"]
	
	// 获取map对象大小
    Long size =  stringRedisTemplate.opsForHash().size("redmap"); //2

8、Redis Set:

	//向指定key中存放set集合(String k,String... vs)
	Long stringRedisTemplate.opsForSet().add("redset","1","2","3");//3
	
	//根据key获取set集合(String k)
	Set<String> stringRedisTemplate.opsForSet().members("redset");//["1","2","3"]

	//根据key查看set集合中是否存在指定数据
	boolean stringRedisTemplate.opsForSet().isMember("redset","1");//true
	
	//根据key删除指定的value(String k,Object... objects)
    //2,当所有的value均被删除,redset这个key注销
	Long stringRedisTemplate.opsForSet().remove("redset","1","2");

四、Redis客户端工具下载:

Redis Desktop Manager

Another Redis Desktop Manager   (集群环境推荐使用)

参考链接

如果本篇文章对你有帮助的话,很高兴能够帮助上你。

当然,如果你觉得文章有什么让你觉得不合理、或者有更简单的实现方法又或者有理解不来的地方,希望你在看到之后能够在评论里指出来,我会在看到之后尽快的回复你。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年12月19日
下一篇 2023年12月19日

相关推荐