SpringData之Spring-Redis使用

上一篇簡單介紹了Redis,本文介紹一下如何操作Redis。對於現有的操作Redis比較知名的框架有Jedis(歷史悠久)和Lettuce(後來居上,大有趕超之勢,推薦使用lettuce,他是基於netty實現的非阻塞redis客戶端,並且同時提供同步和異步的API,具體介紹請移步官網)。SpringData對Jedis與Lettuce做了封裝方便我們開發,這裏主要介紹一下Spring-Redis的使用。

搭建Spring-Redis環境

首先建立Spring Boot項目,maven文件如下:

Redis的配置類如下:

和JDBC與MQ一樣,要連接上Redis,我們首先需要先注入連接工廠,Spring-Redis對應Jedis和Lettuce的連接工廠分別是JedisConnectionFactory和LettuceConnectionFactory。

注入連接工廠後,相信大家已經很熟悉Spring的套路了,Spring通過RedisTemplate來操作redis(注:因爲我們平常對redis都是字符串操作,spring提供了StringRedisTemplate方便我們開發)。

以上基本的環境就搭建好了,接下來讓我們編寫相關方法對Redis進行操作。

簡單測試:

爲了方便起見,我們直接將操作寫在controller裏,代碼格式也瞎寫了。

啓動項目,當我們訪問 “redis/add” 時,就會看到剛剛存入Redis的Person字符串了。注意上面的ValueOperations,他是Spring提供給我們方便操作Redis 中值數據類型爲String的類(還記得Redis中的數據類型有多少嗎?),Spring對Redis中每個數據類型都提供了對應的操作類。操作類也可以通過redisTemplate.opsForValue()方法獲取。注意,如果你用的開發工具是Idea,resource註解按上面的寫法注入時會提示注入錯誤,這時需要我們修改一下Idea中關於Spring 注入的提示級別即可。

序列化器:

上面我們存入的是字符串,如果我想存入一個我們自定義的JavaBean呢?Spring也爲我們提供了極其方便得方法使我們可以直接存入,我們調用redisTemplate.opsForHash().put("t","l",new Person(2,"zz"));,我們發現此時並不需要進行手動的將其轉換爲字符串,這是因爲Spring提供了默認的JdkSerializationRedisSerializer序列化器,它在我們存入的時候自動幫我們進行序列化。默認的序列化器由名字可知,使用的是JDK的序列化機制,這就要求我們的bean需要實現Serializable接口。Spring提供了很多其他的序列化器,比如支持json的Jackson2JsonRedisSerializer,支持xml的OxmSerializer,要使用他們只需要在template中進行一下set即可。

事務操作:

Redis的事務可以理解爲一個批量執行腳本,單個 Redis 命令的執行是原子性的,但 Redis 事務的執行並不是原子性的,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成後續的指令不做。這是Redis事務與普通數據庫事務行爲的不同之處。我們可以在事務執行時對指定的key進行watch操作,這樣在事務執行過程中若有其他線程對該key做了操作,那麼事務會被打斷。

讓我們使用Spring完成一個事務的操作,由於默認情況下Spring不保證事務中所有的操作都通過一個connection完成,Spring提供了SessionCallback來保證事務中的操作在一個連接上完成。

返回值txResult是一個LIst,每一項代表了語句是否執行成功,訪問/redis/tx我們可以看到返回值爲1並且控制檯成功打印,表明該條語句執行成功。

我們也可以在Redis的config類中開啓全局的事務配置,這樣的話默認情況下所有的set操作都會在事務中執行,讀操作不會在事務中執行。

批量操作:

Redis提供了pipline來進行批量操作,嗯。。使用方法和事務操作類似,也是使用sessionCallback,就不想截圖了。。。

對於LUA腳本的支持:

由於多個Redis命令原子化時,Lua腳本爲我們提供了支持,我們一般使用Lua腳本作爲Redis分佈式鎖的解鎖工作(加鎖使用set命令,忘記那個版本後set命令可以指定多個參數,通過她我們可以實現加鎖的原子性),Spring下開發LUA腳本十分簡單,他爲我們提供了非常Java化的操作方式,我們先將腳本註冊爲bean

接下來使用就跟我們正常調用dao,service裏的方法一樣了。

對於緩存的支持:

Spring-Redis通過Spring-Cache實現緩存。

我們先來說一下Spring-Cache,Spring-Cache主要緩存的是方法的結果,這樣對於一些傳遞參數基本不變且執行成本較高的方法比較適合。Spring本身並不提供緩存存儲的地方,只是緩存的邏輯不需要自己手動編寫,Spring通過CacheManager來實現這種行爲。一般常見的緩存管理器由ConcurrentMap,Ecache(單機緩存的性能很高),或者是本文的Redis。項目中使用Spring緩存一般通過註解的方式,使用也很簡單,讓我們簡單介紹他的常用註解。

@Cacheable(cacheNames="",key="",sync=true,condition="",unless=""):方法級別,表明該方法會將執行結果存入緩存,下次使用相同參數的調用時會直接返回結果。該註解可以指定多個cacheNames,即多份緩存,但是一般情況下我們都會指定一個name。key代表我們取緩存時的key值,因爲緩存本質上是map的形式,我們需要通過key獲取緩存的value,其中key的指定可以使用EL表達式。sync代表是否將該方法轉爲同步方法用於多線程訪問的情況。condition代表緩存該方法的條件。unless類似於condition也可以用於判斷是否緩存該結果,與condition不同的是,他是在方法執行完成之後才進行判斷。

@CachePut(cacheNames="", key=""):用於將方法的執行結果放入緩存。用於緩存同步,比方說我已經將查詢結果放入緩存,這時我對數據庫內容進行了更新,但緩存中還是舊的數據,這時就需要在數據庫更新方法上用到該註解。

@CacheEvict(cacheNames="",allEntries=true):即緩存清除,和@CachePut對立,allEntries代表是否刪除該緩存空間中所有的緩存,beforeInvocation屬性代表是否在方法體執行之前進行刪除。

@Caching:支持同時寫入多個@CacheEvict或@CachePut。

@CacheConfig:類級別的註解,用於配置一些公用值。

@EnableCaching:這個就不用說了。。Spring Boot所有開啓xx功能的註解都是以Enable開頭。

說完了基礎,接下來我們就來配置Redis的cacheManager,然後在啓動類上加上@EnableCaching註解

這個是最簡單的cacheManager配置方式,如果想進行其他的個性化設置的話,可以通過RedisCacheManager的build模式進行創建,並設置相應的RedisCacheConfiguration,具體設置項可以去官網查看,這裏不詳細介紹了。配置完之後,給出測試方法

我們可以看到,當我們連續兩次請求get時並且參數相同,控制檯只會打印一次,說明我們的緩存生效。

此時我們查看Redis數據庫,也會看到Spring寫進Redis的緩存。

Redis Repositories:

如果你使用過Spring-JPA的話對Repositories應該不會陌生,我們通過繼承各種Repositories接口後就可以直接使用其中的方法完成增刪改查等一系列操作。Redis Repositories與其類似,但是它主要用於Redis的Hash類型,通過它我們可以方便的進行實體類與Redis hash類型的轉換。

其中的@RedisHash註解表明存入Redis中hash的名稱,@id代表hash中的key。接下來需要在Redis配置類上加入@EnableRedisRepositories註解,並編寫接口實現相應的Repository接口。

這裏我們繼承CrudRepository接口,對於該系列接口不熟悉的同學請移步Spring-JPA。

接下來讓我們編寫測試方法。

我們可以看到已經可以取出保存進去的user對象了。讓我們再來看下redis數據庫中的內容:

可以看到,我們的user對象已經正常的存入redis中了。如果我們想要設置存在redis中對象的過期時間,只需要在實體類中加入表示時間的字段並加上@TimeToLive註解即可。

end:

好了,關於Spring-Redis就差不多介紹完了,有想詳細瞭解的同學請移步官網。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章