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