1、背景介紹
Redis
作為緩存工具,大部分項目中會經(jīng)常用到。為方便以后快速集成Redis
,現(xiàn)將SpringBoot 集成Redis
實踐過程記錄如下慌核。
2、springboot 集成redis步驟
1申尼、pom包引入Redis依賴
<!-- 引用Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
# 注意:
<!--這里我使用的springboot 2.2.1-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath />
</parent>
2垮卓、yml文件配置Redis相關
spring:
application:
name: redis-demo
redis:
host: localhost
database: 1
jedis: # 配置jedis線程池,也可以配置Lettuce
pool:
max-active: 8 # 最大活動數(shù)量()
max-wait: -1 # 連接池最大阻塞時間 (使用負數(shù)表示沒有限制)
port: 6379 # 6379默認端口师幕,不配置就取默認
# --lettuce 配置
# lettuce:
# pool:
# max-active:
注:
這里可以選用redis 的lettuce
client端粟按。配置和 jedis
一致。
3霹粥、編寫RedisConfig配置類
/**
* All rights Reserved, Designed By www.pousheng.com
*
* @version V1.0
* @Title: RedisConfig
* @Package com.lsy.redisdemo.config
* @Description: 簡單描述下這個類是做什么用的
* */
@Configuration
public class RedisConfig {
/**
* @name: redisTemplate
* @description: RedisTemplate
* @param redisConnectionFactory
* @return: org.springframework.data.redis.core.RedisTemplate<java.lang.String,java.lang.Object>
* @date: 2020-12-04 13:19
*
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer(Object.class);
// 設置鍵(key)的序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 設置value序列化
redisTemplate.setValueSerializer(serializer);
// 設置HashKey序列化 為啥要hashkey
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 設置HashValue序列化
redisTemplate.setHashValueSerializer(serializer);
// 默認序列化
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
到這里灭将,簡單Redis集成
已經(jīng)完成了,使用到地方后控,直接@Autowired
redisTemplate 即可庙曙。
@Autowired
private RedisTemplate redisTemplate;
接下來就將不同數(shù)據(jù)類型操作整理如下:
3、redisTemplate 對于不同數(shù)據(jù)結構的Curd舉例:
redisTemplate.opsForList();//操作list
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForCluster();//集群時使用
redisTemplate.opsForGeo();//地理位置時使用
redisTemplate.opsForHash();//操作散列
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
redisTemplate.opsForHyperLogLog(); //操作有序set
3.1 字符串類型
opsForValue
常用方法說明如下:
-
setIfAbsent
:(absent缺席)如果鍵不存在則新增,如果存在則不改變已經(jīng)有的值浩淘。 -
setIfPresent
: (present出席)如果鍵不存在則不新增捌朴,如果存在則修改。 -
append
: 在當前key
對應的value
后面追加value
张抄。 -
increment(key, value)
: 用戶值為數(shù)字加法砂蔽,value值,如果value為空署惯,則對于key自增1 -
decrement
: 用戶值為數(shù)字類型的減法左驾,value值有就減少value個單位。 -
mutiSet(map)
: 批量設置字符串鍵值极谊。 -
mutiGet(Collection)
: 批量查詢什荣,返回對應批量key值的value值集合list。 -
size
: 返回鍵對應的值存儲長度怀酷。
redisTemplate.opsForValue().setIfAbsent(key,value,timeoutR, TimeUnit.DAYS);
redisTemplate.opsForValue().setIfPresent(key,value,timeoutR, TimeUnit.DAYS);
3.2 散列類型
opsForHash()
常用方法如下:
-
putIfAbsent(key,hashkey,value)
: 追加key下的hashkey字段及對應的value值, 如果hashkey存在,則不追加value值嗜闻,如果hashkey不存在則追加蜕依。 -
putAll(key,Map)
: 增加key對應的hash對象,如果key存在則修改原本hash對象,修改規(guī)則:修改map中的字段匹配到hashkey的hashvalue值样眠,如果map中的字段無法匹配hashkey,則不會新增hashkey和hashvalue友瘤,原本hash對象中多出的hash鍵值對保持不變。 -
put(key,hashkey,hashvalue)
: 增加key對應hash對象字段及字段值屬性檐束,如果key存在會修改hashkey或者新增hashkey操作(hashkey不存在) -
delete(key,hashkey)
: 刪除key下的hashkey辫秧,hashkey傳入一個或多個。 -
values(key)
: 返回key下所有hashkey對應的hashvalue值的集合list
被丧。
【示例】
key:123456 對應的hash對象如下:
image.png
執(zhí)行putALL
方法盟戏,key:123456
Map對象值如下,與redis中已經(jīng)存在的比較甥桂,減少了"mobile"柿究,增加了"birthday"。
{
"id": "123456",
"userName": "usr",
"memberId": "337462",
"birthday": "2021-06-08 16:42:01"
}
執(zhí)行結果如下:
image.png
3.3 列表類型
現(xiàn)有列表如下:
image.png
opsForList
常用方法說明
-
range(key,start,end)
: 列表查詢,返回列表:start指的是列表下標黄选,列表第一位0開始,end列表下標(包含下標后面的元素:"( , ]" )蝇摸。 -
leftpush(key,value)
: 從列表左邊方式插入元素,如果key不存在則新增key對應的列表 -
leftPush(key,pivot,value)
: 查找列表中pivot元素前面插入value值 -
rightpush(key,value)
: 從列表右邊方式插入元素办陷,如果key不存在則新增key對應的列表 -
set(key,index,value)
:修改列表中index位置的元素 -
size(key)
: 列表的大小 -
rightPopAndLeftPush(key,destination)
: 從當前列表右邊pop一個元素并從左邊插入到 destination目標列表貌夕。
3.3 set集合型類型
opsForSet
常用方法說明:
-
add(key,value)
: 添加集合元素,如果集合不存在則新增. -
members(key)
: 列出所有集合中的元素集. -
isMember(key,member)
: 判斷member是否存在集合key值中. -
intersect(key1, key2)
: 求交集民镜,返回集合key1, key2的共有的元素集. -
difference(key1,key2)
: 求差集啡专,返回僅存在key1中的元素集. -
union(key1,key2)
: 求并集,返回集合key1,key2中所有不重復元素集. -
remove(key , value)
: 刪除集合key中的元素value. -
size(key)
: 查看集合的大小
3.4 zset有序集合類型
opsForZSet
常用方法說明
-
add(key , value, score)
: 添加有序集合殃恒,如果集合不存在則新增 -
range(key,start,stop)
: 獲取redis有序集合范圍類元素植旧,按默認排序索引(分數(shù)從小到大)
4、redisTemplate中管理redis事務
RedisTemplate來操作Redis离唐,關于事務操作的時候會有問題:
public void redisMulti(String key, Long increment){
// redis事務開啟
redisTemplate.multi();
redisTemplate.opsForValue().increment(key,increment);
redisTemplate.opsForValue().increment(key,increment);
redisTemplate.opsForValue().increment(key,increment);
redisTemplate.opsForValue().increment(key,increment);
redisTemplate.exec();
}
原本以為按照如下操作redis事務病附,但斷點在exec
地方,還未執(zhí)行exec()
方法亥鬓,redis客戶端里就已近存有key的計算結果完沪。當執(zhí)行完畢后會報如下錯誤:
21-06-10 14:04:07.721 ERROR 80076 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/redis-demo] threw exception [Request processing failed; nested exception is org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTI] with root cause
io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTI
at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:135) ~[lettuce-core-5.1.7.RELEASE.jar:na]
at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:108) ~[lettuce-core-5.1.7.RELEASE.jar:na]
省略
原因是配置redisTemplate地方未開啟事務,增加如下部分:
// 開啟事務
redisTemplate.setEnableTransactionSupport(true);