javascript
Spring操作Redis
在 Spring 中使用 Redis,除了需要 jedis.jar 外,還需要下載 spring-data-redis.jar,這里值得注意的是 jar 包和 Spring 版本兼容的問題,我使用的 jar 包版本是 1.8.1,而 Spring 的版本是 5.0.4,如果使用其他的版本可能存在不兼容的問題,從而產(chǎn)生異常。
把下載的 jar 包導(dǎo)入到工程環(huán)境中,這樣就可以在使用 Spring 提供的 RedisTemplate 操作 Redis 了,只是在使用前,需要對 Spring 提供的方案進行探討,以便更好地使用它們。
在大部分情況下我們都會用到連接池,于是先用 Spring 配置一個 JedisPoolConfig 對象,這個配置相對而言比較簡單,使用 Spring 配置 JedisPoolConfig 對象代碼如下所示。
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><!-- 最大空閑數(shù) --><property name="maxIdle" value="50" /><!-- 最大連接數(shù) --><property name="maxTotal" value="100" /><!-- 最大等待時間 --><property name="maxWaitMillis" value="20000" /> </bean>這樣就設(shè)置了一個連接池的配置,繼續(xù)往下配置。
在使用 Spring 提供的 RedisTemplate 之前需要配置 Spring 所提供的連接工廠,在 Spring Data Redis 方案中它提供了 4 種工廠模型。
JredisConnectionFactory。JedisConnectionFactory。LettuceConnectionFactory。SrpConnectionFactory。雖然使用哪種實現(xiàn)工廠都是可以的,但是要根據(jù)環(huán)境進行測試,以驗證使用哪個方案的性能是最佳的。無論如何它們都是接口 RedisConnectionFactory 的實現(xiàn)類,更多的時候我們都是通過接口定義去理解它們,所以它們是具有接口適用性特性的。我將以使用最為廣泛的 JedisConnectionFactory 為例進行講解。
例如,在 Spring 中配置一個 JedisConnectionFactory 對象,配置 JedisConnectionFactory 代碼如下所示。
<bean id="connectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="localhost" /><property name="port" value="6379" /><!--<property name="password" value="password"/> --><property name="poolConfig" ref="poolConfig" /> </bean>解說
hostName,代表的是服務(wù)器,默認(rèn)值是 localhost,所以如果是本機可以不配置它。port,代表的是接口端口,默認(rèn)值是 6379,所以可以使用默認(rèn)的 Redis 端口,也可以不配置它。password,代表的是密碼,在需要密碼連接 Redis 的場合需要配置它。poolConfig,是連接池配置對象,可以設(shè)置連接池的屬性。我們完成了一個 Redis 連接工廠的配置。這里配置的是 JedisConnectionFactory,如果需要的是 LettuceConnectionFactory,可以把使用 Spring 配置 JedisPoolConfig 對象代碼中的 Bean 元素的 class 屬性修改為 org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor 即可,這取決于項目的需要和特殊性。有了 RedisConnectionFactory 工廠,就可以使用 RedisTemplate 了。
普通的連接使用沒有辦法把 Java 對象直接存入 Redis,而需要我們自己提供方案,這時往往就是將對象序列化,然后使用 Redis 進行存儲,而取回序列化的內(nèi)容后,在通過轉(zhuǎn)換轉(zhuǎn)變?yōu)?Java 對象,Spring 模板中提供了封裝的方案,在它內(nèi)部提供了 RedisSerializer 接口(org.springframework.data.redis.serializer.RedisSerializer)和一些實現(xiàn)類。
可以選擇 Spring 提供的方案去處理序列化,當(dāng)然也可以去實現(xiàn)在 spring data redis 中定義的 RedisSerializer 接口,在 Spring 中提供了以下幾種實現(xiàn) RedisSerializer 接口的序列化器。
GenericJackson2JsonRedisSerializer,通用的使用 Json2.jar 的包,將 Redis 對象的序列化器。Jackson2JsonRedisSerializer<T>,通過 Jackson2.jar 包提供的序列化進行轉(zhuǎn)換(由于版本太舊,Spring 不推薦使用)。JdkSerializationRedisSerializer<T>,使用 JDK 的序列化器進行轉(zhuǎn)化。OxmSerializer,使用 Spring O/X 對象 Object 和 XML 相互轉(zhuǎn)換。StringRedisSerializer,使用字符串進行序列化。GenericToStringSerializer,通過通用的字符串序列化進行相互轉(zhuǎn)換。使用它們就能夠幫助我們把對象通過序列化存儲到 Redis 中,也可以把 Redis 存儲的內(nèi)容轉(zhuǎn)換為 Java 對象,為此 Spring 提供的 RedisTemplate 還有兩個屬性。
keySerializer——鍵序列器。valueSerializer——值序列器。有了上面的了解,就可以配置 RedisTemplate 了。選用 StringRedisSerializer 作為 Redis 的 key 的序列化器,而使用 JdkSerializationRedisSerializer 作為其 value 的序列化器,則可以以下代碼的方法來配置 RedisTemplate。
<bean id="jdkSerializationRedisSerializer"class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> <bean id="stringRedisSerializer"class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="connectionFactory" /><property name="keySerializer" ref="stringRedisSerializer" /><property name="valueSerializer" ref="jdkSerializationRedisSerializer" /> </bean>這樣就配置了一個 RedisTemplate 的對象,并且 spring data redis 知道會用對應(yīng)的序列化器去轉(zhuǎn)換 Redis 的鍵值。
舉個例子,新建一個角色對象,使用 Redis 保存它的對象,使用 Redis 保存角色類對象如下所示。
package com.pojo; import java.io.Serializable; public class Role implements Serializable {/*** 注意,對象要可序列化,需要實現(xiàn)Serializable接口,往往要重寫serialVersionUID*/private static final long serialVersionUID = 3447499459461375642L;private long id;private String roleName;private String note;//省略setter和getter方法 }因為要序列化對象,所以需要實現(xiàn) Serializable 接口,表明它能夠序列化,而 serialVersionUID 代表的是序列化的版本編號。
接下來就可以測試保存這個 Role 對象了,測試代碼如下所示。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class); Role role = new Role(); role.setId(1L); role.setRoleName("role_name_1"); role.setNote ("note_l"); redisTemplate.opsForValue().set("role_1", role); Role role1 = (Role) redisTemplate.opsForValue().get ("role_1"); System.out.println(role1.getRoleName());在 System.out.println(role1.getRoleName()) ;這行打下斷點,會發(fā)現(xiàn)這里已經(jīng)成功保存和獲取了一個 Java 對象,這段代碼演示的是如何使用 StringRedisSerializer 序列化 Redis 的 key,而使用 JdkSerializationRedisSerializer 序列化 Redis 的value,當(dāng)然也可以根據(jù)需要去選擇,甚至是自定義序列化器。
注意:以上的使用都是基于 RedisTemplate、基于連接池的操作,換句話說,并不能保證每次使用 RedisTemplate 是操作同一個對 Redis 的連接,比如上面代碼中的下面兩行代碼。set 和 get 方法看起來很簡單,它可能就來自于同一個 Redis 連接池的不同 Redis 的連接。
為了使得所有的操作都來自于同一個連接,可以使用 SessionCallback 或者 RedisCallback 這兩個接口,而 RedisCallback 是比較底層的封裝,其使用不是很友好,所以更多的時候會使用 SessionCallback 這個接口,通過這個接口就可以把多個命令放入到同一個 Redis 連接中去執(zhí)行,代碼如下所示,它主要是實現(xiàn)了上面代碼中的功能。
package redisDemo;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SessionCallback;import com.pojo.Role;public class Test {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");RedisTemplate<String, Role> redisTemplate = applicationContext.getBean(RedisTemplate.class);Role role = new Role();role.setId(1L);role.setRoleName("role_name_1");role.setNote("role_note_1");SessionCallback callBack = new SessionCallback<Role>() {@Overridepublic Role execute(RedisOperations ops) throws DataAccessException {ops.boundValueOps("role_1").set(role);return (Role) ops.boundValueOps("role_1").get();}};Role savedRole = (Role) redisTemplate.execute(callBack);System.out.println(savedRole.getId());} }這樣 set 和 get 命令就能夠保證在同一個連接池的同一個 Redis 連接進行操作。
總結(jié)
以上是生活随笔為你收集整理的Spring操作Redis的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Sublime Text3终极宝典
- 下一篇: Spring Boot 之 elasti