一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 在Java中使用redisTemplate操作緩存的方法示例

在Java中使用redisTemplate操作緩存的方法示例

2021-07-10 11:37detectiveHLH Java教程

這篇文章主要介紹了在Java中使用redisTemplate操作緩存的方法示例,在Redis中可以存儲String、List、Set、Hash、Zset。感興趣的可以了解一下

背景

在最近的項目中,有一個需求是對一個很大的數據庫進行查詢,數據量大概在幾千萬條。但同時對查詢速度的要求也比較高。

這個數據庫之前在沒有使用presto的情況下,使用的是hive,使用hive進行一個簡單的查詢,速度可能在幾分鐘。當然幾分鐘也并不完全是跑sql的時間,這里面包含發請求,查詢數據并且返回數據的時間的總和。但是即使這樣,這樣的速度明顯不能滿足交互式的查詢需求。

我們的下一個解決方案就是presto,在使用了presto之后,查詢速度降到了秒級。但是對于一個前端查詢界面的交互式查詢來說,十幾秒仍然是一個不能接受的時間。

雖然presto相比hive已經快了很多(facebook官方宣稱的是10倍),但是對分頁的支持不是很友好。我在使用的時候是自己在后端實現的分頁。

在這種情況下應用緩存實屬無奈之舉。講道理,優化應從底層開始,自底而上。上層優化的方式和效率感覺都很有局限。

<!--more-->

為什么要使用緩存

前端查詢中,單次查詢的匹配數據量有可能會達到上百甚至上千條,在前端中肯定是需要分頁展示的。就算每次查詢10條數據,整個查詢也要耗時6-8s的時間。想象一下,每翻一頁等10s的場景。

所以,此時使用redis緩存。減少請求數據庫的次數。將匹配的數據一并存入數據庫。這樣只有在第一次查詢時耗費長一點,一旦查詢完成,用戶點擊下一頁就是毫秒級別的操作了。

使用redistemplate

spring封裝了一個比較強大的模板,也就是redistemplate,方便在開發的時候操作redis緩存。在redis中可以存儲string、list、set、hash、zset。下面將針對list和hash分別介紹。

list

redis中的list為簡單的字符串列表,常見的有下面幾種操作。

haskey

判斷一個鍵是否存在,只需要調用haskey就可以了。假設這個key是test,具體用法如下。

?
1
2
3
4
5
if (redistemplate.haskey("test")) {
  system.out.println("存在");
} else {
  system.out.println("不存在");
}

range

該函數用于從redis緩存中獲取指定區間的數據。具體用法如下。

?
1
2
3
4
5
6
7
8
9
10
11
if (redistemplate.haskey("test")) {
  // 該鍵的值為 [4, 3, 2, 1]
  system.out.println(redistemplate.opsforlist().range("test", 0, 0)); // [4]
  system.out.println(redistemplate.opsforlist().range("test", 0, 1)); // [4, 3]
  system.out.println(redistemplate.opsforlist().range("test", 0, 2)); // [4, 3, 2]
  system.out.println(redistemplate.opsforlist().range("test", 0, 3)); // [4, 3, 2, 1]
  system.out.println(redistemplate.opsforlist().range("test", 0, 4)); // [4, 3, 2, 1]
  system.out.println(redistemplate.opsforlist().range("test", 0, 5)); // [4, 3, 2, 1]
  
  system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [4, 3, 2, 1] 如果結束位是-1, 則表示取所有的值
}

delete

刪除某個鍵。

?
1
2
3
4
5
6
7
8
9
10
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
 
redistemplate.opsforlist().rightpushall("test", test);
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [1, 2, 3, 4]
redistemplate.delete("test");
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // []

size

獲取該鍵的集合長度。

?
1
2
3
4
5
6
7
8
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
 
redistemplate.opsforlist().rightpushall("test", test);
system.out.println(redistemplate.opsforlist().size("test")); // 4

leftpush

我們把存放這個值的地方想象成如圖所示的容器。

container

在Java中使用redisTemplate操作緩存的方法示例

并且取數據總是從左邊取,但是存數據可以從左也可以從右。左就是leftpush,右就是rightpush。leftpush如下圖所示。

left-push

在Java中使用redisTemplate操作緩存的方法示例

用法如下。

?
1
2
3
4
5
for (int i = 0; i < 4; i++) {
  integer value = i + 1;
  redistemplate.opsforlist().leftpush("test", value.tostring());
  system.out.println(redistemplate.opsforlist().range("test", 0, -1));
}

控制臺輸出的結果如下。

[1]
[2, 1]
[3, 2, 1]
[4, 3, 2, 1]

leftpushall

基本和leftpush一樣,只不過是一次性的將list入棧。

?
1
2
3
4
5
6
7
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().leftpushall("test", test);
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [4, 3, 2, 1]

當然你也可以這樣

?
1
2
redistemplate.opsforlist().leftpushall("test", test);
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [4, 3, 2, 1]

leftpushifpresent

leftpush是同樣的操作,唯一的不同是,當且僅當key存在時,才會更新key的值。如果key不存在則不會對數據進行任何操作。

?
1
2
3
4
5
redistemplate.delete("test");
 
redistemplate.opsforlist().leftpushifpresent("test", "1");
redistemplate.opsforlist().leftpushifpresent("test", "2");
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // []

leftpop

該函數用于移除上面我們抽象的容器中的最左邊的一個元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().rightpushall("test", test);
 
redistemplate.opsforlist().leftpop("test"); // [2, 3, 4]
redistemplate.opsforlist().leftpop("test"); // [3, 4]
redistemplate.opsforlist().leftpop("test"); // [4]
redistemplate.opsforlist().leftpop("test"); // []
redistemplate.opsforlist().leftpop("test"); // []

值得注意的是,當返回為空后,在redis中這個key也不復存在了。如果此時再調用leftpushifpresent,是無法再添加數據的。有代碼有真相。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().rightpushall("test", test);
 
redistemplate.opsforlist().leftpop("test"); // [2, 3, 4]
redistemplate.opsforlist().leftpop("test"); // [3, 4]
redistemplate.opsforlist().leftpop("test"); // [4]
redistemplate.opsforlist().leftpop("test"); // []
redistemplate.opsforlist().leftpop("test"); // []
 
redistemplate.opsforlist().leftpushifpresent("test", "1"); // []
redistemplate.opsforlist().leftpushifpresent("test", "1"); // []

rightpush

rightpush如下圖所示。

right-push

在Java中使用redisTemplate操作緩存的方法示例

用法如下。

?
1
2
3
4
5
for (int i = 0; i < 4; i++) {
  integer value = i + 1;
  redistemplate.opsforlist().leftpush("test", value.tostring());
  system.out.println(redistemplate.opsforlist().range("test", 0, -1));
}

控制臺輸出的結果如下。

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]

rightpushall

同rightpush,一次性將list存入。

?
1
2
3
4
5
6
7
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().leftpushall("test", test);
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [1, 2, 3, 4]

當然你也可以這樣。

?
1
2
redistemplate.opsforlist().rightpushall("test", "1", "2", "3", "4");
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [1, 2, 3, 4]

rightpushifpresent

rightpush是同樣的操作,唯一的不同是,當且僅當key存在時,才會更新key的值。如果key不存在則不會對數據進行任何操作。

?
1
2
3
4
5
redistemplate.delete("test");
 
redistemplate.opsforlist().rightpushifpresent("test", "1");
redistemplate.opsforlist().rightpushifpresent("test", "2");
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // []

rightpop

該函數用于移除上面我們抽象的容器中的最右邊的一個元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().rightpushall("test", test);
 
redistemplate.opsforlist().rightpop("test"); // [1, 2, 3]
redistemplate.opsforlist().rightpop("test"); // [1, 2]
redistemplate.opsforlist().rightpop("test"); // [1]
redistemplate.opsforlist().rightpop("test"); // []
redistemplate.opsforlist().rightpop("test"); // []

與leftpop一樣,返回空之后,再調用rightpushifpresent,是無法再添加數據的。

index

獲取list中指定位置的元素。

?
1
2
3
4
5
6
7
8
9
10
if (redistemplate.haskey("test")) {
  // 該鍵的值為 [1, 2, 3, 4]
  system.out.println(redistemplate.opsforlist().index("test", -1)); // 4
  system.out.println(redistemplate.opsforlist().index("test", 0)); // 1
  system.out.println(redistemplate.opsforlist().index("test", 1)); // 2
  system.out.println(redistemplate.opsforlist().index("test", 2)); // 3
  system.out.println(redistemplate.opsforlist().index("test", 3)); // 4
  system.out.println(redistemplate.opsforlist().index("test", 4)); // null
  system.out.println(redistemplate.opsforlist().index("test", 5)); // null
}

值得注意的有兩點。一個是如果下標是-1的話,則會返回list最后一個元素,另一個如果數組下標越界,則會返回null

trim

用于截取指定區間的元素,可能你會理解成與range是一樣的作用。看了下面的代碼之后應該就會立刻理解。

?
1
2
3
4
5
6
7
8
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
redistemplate.opsforlist().rightpushall("test", test); // [1, 2, 3, 4]
 
redistemplate.opsforlist().trim("test", 0, 2); // [1, 2, 3]

其實作用完全不一樣。range是獲取指定區間內的數據,而trim是留下指定區間的數據,刪除不在區間的所有數據。trimvoid,不會返回任何數據。

remove

用于移除鍵中指定的元素。接受3個參數,分別是緩存的鍵名,計數事件,要移除的值。計數事件可以傳入的有三個值,分別是-101

-1代表從存儲容器的最右邊開始,刪除一個與要移除的值匹配的數據;0代表刪除所有與傳入值匹配的數據;1代表從存儲容器的最左邊開始,刪除一個與要移除的值匹配的數據。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
test.add("4");
test.add("3");
test.add("2");
test.add("1");
 
redistemplate.opsforlist().rightpushall("test", test); // [1, 2, 3, 4, 4, 3, 2, 1]
 
// 當計數事件是-1、傳入值是1時
redistemplate.opsforlist().remove("test", -1, "1"); // [1, 2, 3, 4, 4, 3, 2]
 
// 當計數事件是1,傳入值是1時
redistemplate.opsforlist().remove("test", 1, "1"); // [2, 3, 4, 4, 3, 2]
 
// 當計數事件是0,傳入值是4時
redistemplate.opsforlist().remove("test", 0, "4"); // [2, 3, 3, 2]

rightpopandleftpush

該函數用于操作兩個鍵之間的數據,接受三個參數,分別是源key、目標key。該函數會將源key進行rightpop,再將返回的值,作為輸入參數,在目標key上進行leftpush。具體代碼如下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list<string> test = new arraylist<>();
test.add("1");
test.add("2");
test.add("3");
test.add("4");
 
list<string> test2 = new arraylist<>();
test2.add("1");
test2.add("2");
test2.add("3");
 
redistemplate.opsforlist().rightpushall("test", test); // [1, 2, 3, 4]
redistemplate.opsforlist().rightpushall("test2", test2); // [1, 2, 3]
 
redistemplate.opsforlist().rightpopandleftpush("test", "test2");
 
system.out.println(redistemplate.opsforlist().range("test", 0, -1)); // [1, 2, 3]
system.out.println(redistemplate.opsforlist().range("test2", 0, -1)); // [4, 1, 2, 3]

hash

存儲類型為hash其實很好理解。在上述的list中,一個redis的key可以理解為一個list,而在hash中,一個redis的key可以理解為一個hashmap。

put

用于寫入數據。

?
1
2
3
4
5
6
7
8
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring()); // [1, 2, 3, 4]
redistemplate.opsforhash().put("test", "isadmin", true); // true

putall

用于一次性向一個hash鍵中添加多個key。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list<string> list2 = new arraylist<>();
list2.add("5");
list2.add("6");
list2.add("7");
list2.add("8");
map<string, string> valuemap = new hashmap<>();
valuemap.put("map1", list.tostring());
valuemap.put("map2", list2.tostring());
 
redistemplate.opsforhash().putall("test", valuemap); // {map2=[5, 6, 7, 8], map1=[1, 2, 3, 4]}

putifabsent

用于向一個hash鍵中寫入數據。當key在hash鍵中已經存在時,則不會寫入任何數據,只有在hash鍵中不存在這個key時,才會寫入數據。

同時,如果連這個hash鍵都不存在,redistemplate會新建一個hash鍵,再寫入key。

?
1
2
3
4
5
6
7
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
redistemplate.opsforhash().putifabsent("test", "map", list.tostring());
system.out.println(redistemplate.opsforhash().entries("test")); // {map=[1, 2, 3, 4]}

get

用于獲取數據。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
system.out.println(redistemplate.opsforhash().get("test", "map")); // [1, 2, 3, 4]
system.out.println(redistemplate.opsforhash().get("test", "isadmin")); // true
 
boolean bool = (boolean) redistemplate.opsforhash().get("test", "isadmin");
system.out.println(bool); // true
 
string str = redistemplate.opsforhash().get("test", "map").tostring();
list<string> array = jsonarray.parsearray(str, string.class);
system.out.println(array.size()); // 4

值得注意的是,使用get函數獲取的數據都是object類型。

所以需要使用類型與上述例子中的布爾類型的話,則需要強制轉換一次。list類型則可以使用fastjson這種工具來進行轉換。轉換的例子已列舉在上述代碼中。

delete

用于刪除一個hash鍵中的key。可以理解為刪除一個map中的某個key。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list<string> list2 = new arraylist<>();
list2.add("5");
list2.add("6");
list2.add("7");
list2.add("8");
map<string, string> valuemap = new hashmap<>();
valuemap.put("map1", list.tostring());
valuemap.put("map2", list2.tostring());
 
redistemplate.opsforhash().putall("test", valuemap); // {map2=[5, 6, 7, 8], map1=[1, 2, 3, 4]}
redistemplate.opsforhash().delete("test", "map1"); // {map2=[5, 6, 7, 8]}

values

用于獲取一個hash類型的鍵的所有值。

?
1
2
3
4
5
6
7
8
9
10
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
system.out.println(redistemplate.opsforhash().values("test")); // [[1, 2, 3, 4], true]

entries

用于以map的格式獲取一個hash鍵的所有值。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
map<string, string> map = redistemplate.opsforhash().entries("test");
system.out.println(map.get("map")); // [1, 2, 3, 4]
system.out.println(map.get("map") instanceof string); // true
system.out.println(redistemplate.opsforhash().entries("test")); // {a=[1, 2, 3, 4], isadmin=true}

haskey

用于獲取一個hash鍵中是否含有某個鍵。

?
1
2
3
4
5
6
7
8
9
10
11
12
ist<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
system.out.println(redistemplate.opsforhash().haskey("test", "map")); // true
system.out.println(redistemplate.opsforhash().haskey("test", "b")); // false
system.out.println(redistemplate.opsforhash().haskey("test", "isadmin")); // true

keys

用于獲取一個hash鍵中所有的鍵。

?
1
2
3
4
5
6
7
8
9
10
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
system.out.println(redistemplate.opsforhash().keys("test")); // [a, isadmin]

size

用于獲取一個hash鍵中包含的鍵的數量。

?
1
2
3
4
5
6
7
8
9
10
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
 
redistemplate.opsforhash().put("test", "map", list.tostring());
redistemplate.opsforhash().put("test", "isadmin", true);
 
system.out.println(redistemplate.opsforhash().size("test")); // 2

increment

用于讓一個hash鍵中的某個key,根據傳入的值進行累加。傳入的數值只能是double或者long,不接受浮點型

?
1
2
3
4
5
6
redistemplate.opsforhash().increment("test", "a", 3);
redistemplate.opsforhash().increment("test", "a", -3);
redistemplate.opsforhash().increment("test", "a", 1);
redistemplate.opsforhash().increment("test", "a", 0);
 
system.out.println(redistemplate.opsforhash().entries("test")); // {a=1}

multiget

用于批量的獲取一個hash鍵中多個key的值。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list<string> list2 = new arraylist<>();
list2.add("5");
list2.add("6");
list2.add("7");
list2.add("8");
 
redistemplate.opsforhash().put("test", "map1", list.tostring()); // [1, 2, 3, 4]
redistemplate.opsforhash().put("test", "map2", list2.tostring()); // [5, 6, 7, 8]
 
list<string> keys = new arraylist<>();
keys.add("map1");
keys.add("map2");
 
system.out.println(redistemplate.opsforhash().multiget("test", keys)); // [[1, 2, 3, 4], [5, 6, 7, 8]]
system.out.println(redistemplate.opsforhash().multiget("test", keys) instanceof list); // true

scan

獲取所以匹配條件的hash鍵中key的值。我查過一些資料,大部分寫的是無法模糊匹配,我自己嘗試了一下,其實是可以的。如下,使用scan模糊匹配hash鍵的key中,帶scan的key。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
list<string> list = new arraylist<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list<string> list2 = new arraylist<>();
list2.add("5");
list2.add("6");
list2.add("7");
list2.add("8");
list<string> list3 = new arraylist<>();
list3.add("9");
list3.add("10");
list3.add("11");
list3.add("12");
map<string, string> valuemap = new hashmap<>();
valuemap.put("map1", list.tostring());
valuemap.put("scan_map2", list2.tostring());
valuemap.put("map3", list3.tostring());
 
redistemplate.opsforhash().putall("test", valuemap); // {scan_map2=[5, 6, 7, 8], map3=[9, 10, 11, 12], map1=[1, 2, 3, 4]}
 
cursor<map.entry<string, string>> cursor = redistemplate.opsforhash().scan("test", scanoptions.scanoptions().match("*scan*").build());
if (cursor.hasnext()) {
  while (cursor.hasnext()) {
    map.entry<string, string> entry = cursor.next();
    system.out.println(entry.getvalue()); // [5, 6, 7, 8]
  }
}

引入redistemplate

如果大家看懂了怎么用,就可以將redistemplate引入項目中了。

引入pom依賴

?
1
2
3
4
5
<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-data-redis</artifactid>
  <version>2.0.5.release</version>
</dependency>

新建配置文件

然后需要新建一個redisconfig配置文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.detectivehlh;
 
import com.fasterxml.jackson.annotation.jsonautodetect;
import com.fasterxml.jackson.annotation.propertyaccessor;
import com.fasterxml.jackson.databind.objectmapper;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.data.redis.connection.redisconnectionfactory;
import org.springframework.data.redis.core.redistemplate;
import org.springframework.data.redis.core.stringredistemplate;
import org.springframework.data.redis.serializer.jackson2jsonredisserializer;
 
/**
 * redisconfig
 *
 * @author lunhao hu
 * @date 2019-01-17 15:12
 **/
@configuration
public class redisconfig {
  @bean
  public redistemplate<string, string> redistemplate(redisconnectionfactory factory) {
    objectmapper om = new objectmapper();
    om.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any);
    om.enabledefaulttyping(objectmapper.defaulttyping.non_final);
    //redis序列化
    jackson2jsonredisserializer jackson2jsonredisserializer = new jackson2jsonredisserializer(object.class);
    jackson2jsonredisserializer.setobjectmapper(om);
 
    stringredistemplate template = new stringredistemplate(factory);
    template.setvalueserializer(jackson2jsonredisserializer);
    template.sethashkeyserializer(jackson2jsonredisserializer);
    template.sethashvalueserializer(jackson2jsonredisserializer);
    template.setvalueserializer(jackson2jsonredisserializer);
    template.afterpropertiesset();
    return template;
  }
}

注入

將redistemplate注入到需要使用的地方。

?
1
2
@autowired
private redistemplate redistemplate;

寫在后面

github

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000017940126#leftPush

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品免费aⅴ片在线观看 | 欧美男同互吃gay老头 | 无限在线看免费视频大全 | 男人好大好硬好爽免费视频 | 成 人 亚洲 综合天堂 | 男女小视频在线观看 | 亚洲第一天堂无码专区 | 亚洲AV永久无码精品澳门 | 午夜在线观看免费观看 视频 | 精品精品久久宅男的天堂 | 色综合网天天综合色中文男男 | 久草在线福利资站免费视频 | 久99久热只有精品国产99 | 精品成人片深夜 | 国产乱人乱精一区二区视频密 | 国产xx肥老妇视频奂费 | 国内精品一区二区三区东京 | 国产精品一级香蕉一区 | 亚洲 日韩 国产 中文视频 | 99久久精品自在自看国产 | 免看一级a一片成人123 | 欧美调教打屁股spank视频 | 国产福利一区二区三区四区 | 亚洲欧美另类综合 | 兽操人| 69热视频| 久久精品一区二区三区资源网 | 俄罗斯引擎首页进入 | 俺去俺来也在线www色官网 | 三级全黄裸体 | 麻豆在线传煤 | 午夜香蕉成视频人网站高清版 | 天天做天天爰夜夜爽 | 亚洲第成色999久久网站 | 国产普通话对白露脸流出 | 桃色视频破解版 | 国产婷婷高清在线观看免费 | 国产精品久久久久影院色老大 | 齐天大性之七仙女欲春迅雷链接 | 2048论坛永久入口 原创合集 | 亚洲人成影院午夜网站 |