使用RedisTemplate操作Redis資料庫
目錄
三.RedisTemplate操作Redis資料庫的具體例子
四.RedisTemplate和StringRedisTemplate的區別
一.什麼是Redis
Redis是一個非關係型資料庫,具有很高的存取效能,一般用作快取資料庫,減少正常儲存資料庫的壓力。
Redis可以儲存鍵與5種不同資料結構型別之間的對映,這5種資料結構型別分別為String(字串)、List(列表)、Set(集合)、Hash(雜湊)和 Zset(有序集合)。
下面來對這5種資料結構型別作簡單的介紹:
二.RedisTemplate及其相關方法
1.RedisTemplate
Spring封裝了RedisTemplate物件來進行對Redis的各種操作,它支援所有的Redis原生的api。RedisTemplate位於spring-data-redis包下。RedisTemplate提供了redis各種操作、異常處理及序列化,支援釋出訂閱,並對spring 3.1 cache進行了實現。RedisTemplate提供了redis各種操作、異常處理及序列化,支援釋出訂閱,並對spring 3.1 cache進行了實現。RedisTemplate提供了redis各種操作、異常處理及序列化,支援釋出訂閱,並對spring 3.1 cache進行了實現。RedisTemplate提供了redis各種操作、異常處理及序列化,支援釋出訂閱,並對spring 3.1 cache進行了實現。
注意 RedisTemplate是一個key和value都是泛型的模板類,一般情況下key為String型別,如:RedisTemplate<String,Object>。
此外,如果沒特殊情況,切勿定義成RedisTemplate<Object, Object>,否則根據里氏替換原則,使用的時候會造成型別錯誤 。
spring-data-redis針對jedis提供瞭如下功能:
1.連線池自動管理,提供了一個高度封裝的“RedisTemplate”類
2.針對jedis客戶端中大量api進行了歸類封裝,將同一型別操作封裝為operation介面
ValueOperations:簡單K-V操作
SetOperations:set型別資料操作
ZSetOperations:zset型別資料操作
HashOperations:針對map型別的資料操作
ListOperations:針對list型別的資料操作
2.RedisTemplate中定義了對5種資料結構操作
redisTemplate.opsForValue();//操作字串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
其實這裡的ops相當於options, 是RedisTemplate對各種不同的Redis資料型別進行操作。其實還有另外的方法:
redistempalate.boundValueOps
redistempalate.boundSetOps
redistempalate.boundListOps
redistempalate.boundHashOps
redistempalate.boundZSetOps
opsForXXX和boundXXXOps的區別?
XXX為value的型別,前者獲取一個operator,但是沒有指定操作的物件(key),可以在一個連線(事務)內操作多個key以及對應的value;後者獲取了一個指定操作物件(key)的operator,在一個連線(事務)內只能操作這個key對應的value。
關於計數的API(increment)有一個bug,需要各位使用中注意,通過increment計數以後,通過get方式獲取計數值的時候可能會丟擲EOF異常(和本地的jdk以及redis的編譯版本有關),可以考慮使用boundValueOps(key).get(0,-1)獲取計數值。
三.RedisTemplate操作Redis資料庫的具體例子
1.值型別操作:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")
public class TestValue {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void setValue(){
//存值,針對值型別,ops相當於options
redisTemplate.boundValueOps("name").set("itcast");
}
@Test
public void getValue(){
String str = (String) redisTemplate.boundValueOps("name").get();
System.out.println(str);
}
@Test
public void deleteValue(){
redisTemplate.delete("name");
}
}
2.集合型別操作之Set型別,無序,即存取順序不一定相同
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")
public class TestSet {
@Autowired
private RedisTemplate redisTemplate;
/**
* 存入值
*/
@Test
public void setValue(){
redisTemplate.boundSetOps("nameset").add("曹操");
redisTemplate.boundSetOps("nameset").add("劉備");
redisTemplate.boundSetOps("nameset").add("孫權");
}
/**
* 提取值
*/
@Test
public void getValue(){
Set members = redisTemplate.boundSetOps("nameset").members();
System.out.println(members);
}
/**
* 刪除集合中的某一個值
*/
@Test
public void deleteValue(){
redisTemplate.boundSetOps("nameset").remove("孫權");
}
/**
* 刪除整個集合
*/
@Test
public void deleteAllValue(){
redisTemplate.delete("nameset");
}
}
輸出結果:[孫權, 劉備, 曹操],此外,set型別的元素也不可重複。當set沒有值的時候,會返回一個[]
3.List型別操作
list型別分為兩種,一種是左壓棧,一種是右壓棧
- 右壓棧:
/** * 右壓棧:後新增的物件排在後邊,相當於佇列,相當於先進先出 */ @Test public void testSetValue1(){ redisTemplate.boundListOps("namelist1").rightPush("劉備"); redisTemplate.boundListOps("namelist1").rightPush("關羽"); redisTemplate.boundListOps("namelist1").rightPush("張飛"); } /** * 顯示右壓棧集合,range 表示查詢的索引,從第幾個查到第幾個,如果想查詢所有的數的話只能將第二個數寫得大一點。 */ @Test public void testGetValue1(){ List list = redisTemplate.boundListOps("namelist1").range(0, 10); System.out.println(list); }
執行結果:[劉備, 關羽, 張飛],元素可以重複
-
左壓棧:
/** * 左壓棧:後新增的物件排在前邊,相當於棧,先進後出 */ @Test public void testSetValue2(){ redisTemplate.boundListOps("namelist2").leftPush("劉備"); redisTemplate.boundListOps("namelist2").leftPush("關羽"); redisTemplate.boundListOps("namelist2").leftPush("張飛"); } /** * 顯示左壓棧集合 */ @Test public void testGetValue2(){ List list = redisTemplate.boundListOps("namelist2").range(0, 10); System.out.println(list); }
執行結果:[張飛, 關羽, 劉備]
- 根據索引查詢元素
執行結果:返回索引為1的元素/** * 查詢集合某個元素 */ @Test public void testSearchByIndex(){ String s = (String) redisTemplate.boundListOps("namelist1").index(1); System.out.println(s); }
- 移除某個元素的值
這裡表示移除一個“關羽”。/** * 移除集合某個元素,其中remove中第一個引數是移除的個數 */ @Test public void testRemoveByIndex(){ redisTemplate.boundListOps("namelist1").remove(1, "關羽"); }
4.Hash型別操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext-redis.xml")
public class TestHash {
@Autowired
private RedisTemplate redisTemplate;
// 存值
@Test
public void testSetValue() {
redisTemplate.boundHashOps("namehash").put("a", "唐僧");
redisTemplate.boundHashOps("namehash").put("b", "悟空");
redisTemplate.boundHashOps("namehash").put("c", "八戒");
redisTemplate.boundHashOps("namehash").put("d", "沙僧");
}
//獲取所有的key
@Test
public void testGetKeys() {
Set s = redisTemplate.boundHashOps("namehash").keys();
System.out.println(s);
}
// 獲取所有的value
@Test
public void testGetValues() {
List values = redisTemplate.boundHashOps("namehash").values();
System.out.println(values);
}
// 根據key獲取值
@Test
public void testGetValueByKey() {
Object object = redisTemplate.boundHashOps("namehash").get("b");
System.out.println(object);
}
//根據key移除值
@Test
public void testRemoveValueByKey() {
redisTemplate.boundHashOps("namehash").delete("c");
}
}
四.RedisTemplate和StringRedisTemplate的區別
1. 兩者的關係是StringRedisTemplate繼承RedisTemplate。
2. 兩者的資料是不共通的;也就是說StringRedisTemplate只能管理StringRedisTemplate裡面的資料,RedisTemplate只能管理RedisTemplate中的資料。
3. SDR預設採用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。
StringRedisTemplate預設採用的是String的序列化策略,儲存的key和value都是採用此策略序列化儲存的。
RedisTemplate預設採用的是JDK的序列化策略,儲存的key和value都是採用此策略序列化儲存的。
RedisTemplate使用的序列類在在操作資料的時候,比如說存入資料會將資料先序列化成位元組陣列然後在存入Redis資料庫,這個時候開啟Redis檢視的時候,你會看到你的資料不是以可讀的形式展現的,而是以位元組陣列顯示,類似下面
當然從Redis獲取資料的時候也會預設將資料當做位元組陣列轉化,這樣就會導致一個問題,當需要獲取的資料不是以位元組陣列存在redis當中而是正常的可讀的字串的時候,比如說下面這種形式的資料