spring data redis 理解
前言
Spring Data Redis project,應用了Spring概念來開發使用鍵值形式的數據存儲的解決方案。我們(官方)提供了一個 "template" ,這是一個高級別的抽象,來發送和接收消息。你會註意到它與Spring框架對JDBC的支持有些類似。為什麽選擇Spring Data Redis?
Spring框架,是引領潮流的全棧Java/JEE應用框架。它提供了一個輕量級容器,一種非侵入式的編程模型 -- 這是由依賴註入、AOP、以及便攜的服務抽象開啟的。 SDR框架,使得利用Redis鍵值存儲非常簡單,消除了繁復冗余的任務和呆板的代碼(指獲取連接、釋放資源)。要求
- SDR 1.x要求JDK 6.0及以上
- Redis 2.6.x及以上。在connectors方面,Spring Redis集成了Jedis
連接到Redis
使用Redis和Spring的第一步就是通過IoC容器連接到存儲。想要實現連接,一個java connector(或者binding)是必需的。無論選擇什麽庫,都只有一套SDR API,叫做 org.springframework.data.redis.connection package,以及RedisConnection和RedisConnectionFactory接口,來獲取到Redis的活動連接。
RedisConnection 和 RedisConnectionFactory
註意:對於需要native庫API的情況,RedisConnection提供了專有方法getNativeConnection -- 會返回原生的、底層的用於通信的對象。
活動的RedicConnection由RedisConnectionFactory創建。另外,該工廠還扮演了PersistenceExceptionTranslator,就是說,一旦聲明了,它們會允許用戶進行透明的異常翻譯。例如,通過使用@Repository和AOP的異常翻譯。更多信息,見Spring框架的相關部分。
註意:依賴於底層的配置,工廠會返回一個新的連接 或者 一個現有的連接(使用pool或者shared native connection時)。
使用RedisConnectionFactory最簡單的方式,是通過IoC容器配置相應的connector
重要:不幸的是,目前,不是所有的connector都支持所有的Redis功能。當調用底層庫不支持的API時,會拋出UnsupportedOperationException。這種情況在將來可能被解決,視不同的connector的成熟情況。
配置Jedis connector
1.xml配置
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/>
2.java代碼配置
@Bean public JedisConnectionFactory jedisConnectionFactory(){ return new JedisConnectionFactory(); }
Redis Sentinel支持
為了處理高可用Redis,可以使用RedisSentinelConfiguration來支持Redis Sentinel。註意:目前,只有Jedis和Lettuce支持Redis Sentinel。
/** * jedis */ @Bean public RedisConnectionFactory jedisConnectionFactory() { RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380); return new JedisConnectionFactory(sentinelConfig); } /** * lettuce */ @Bean public RedisConnectionFactory lettuceConnectionFactory() { RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration().master("mymaster").sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380); return new LettuceConnectionFactory(sentinelConfig); }RedisSentinelConfiguration也可以通過PropertySource來定義。
- spring.redis.sentinel.master: master節點的名字
- spring.redis.sentinel.nodes: 以逗號間隔的host:port列表
有時候,需要直接與Sentinels中的某一個進行交互。使用RedisConnectionFactory.getSentinelConnection() 或者RedisConnection.getSentinelCommands(),可以讓你訪問第一個活動的Sentinel。
使用RedisTemplate操作Objects
多數用戶會喜歡使用RedisTemplate和相應的包org.springframework.data.redis.core,該template是Redis模塊的中心類 -- 由於豐富的功能集。該template為Redis交互提供了一個高級別的抽象。當RedisConnection提供了低級別的方法來接受和返還二進制值(byte arrays)時,該template負責了序列化和連接管理,將用戶從這裏細節中解放了出來。 更多地,該template提供了操作視圖(following the grouping from Redis command reference) -- 提供了豐富的接口 來操作特定類型或特定key(通過KeyBound接口),如下:Interface | Description |
---|---|
Key Type Operations |
|
ValueOperations |
Redis string (or value) operations |
ListOperations |
Redis list operations |
SetOperations |
Redis set operations |
ZSetOperations |
Redis zset (or sorted set) operations |
HashOperations |
Redis hash operations |
HyperLogLogOperations |
Redis HyperLogLog operations like (pfadd, pfcount,…) |
GeoOperations |
Redis geospatial operations like |
Key Bound Operations |
|
BoundValueOperations |
Redis string (or value) key bound operations |
BoundListOperations |
Redis list key bound operations |
BoundSetOperations |
Redis set key bound operations |
BoundZSetOperations |
Redis zset (or sorted set) key bound operations |
BoundHashOperations |
Redis hash key bound operations |
BoundGeoOperations |
Redis key bound geospatial operations. |
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/> <!-- redis template definition --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
public class Example { // inject the actual template @Autowired private RedisTemplate<String, String> template; // inject the template as ListOperations -- 自動轉換 @Resource(name="redisTemplate") private ListOperations<String, String> listOps; public void addLink(String userId, URL url) { listOps.leftPush(userId, url.toExternalForm()); } }
聚焦String的便捷類
鑒於使用java.lang.String來作為key/value 存儲到Redis中 非常常見,該Redis模塊還提供了RedisConnection和RedisTemplate的兩個擴展:StringRedisConnection(以及其DefaultStringRedisConnection實現)和StringRedisTemplate。此外,該template和連接,底層使用了StringRedisSerializer。
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/> <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
public class Example { @Autowired private StringRedisTemplate redisTemplate; public void addLink(String userId, URL url) { redisTemplate.opsForList().leftPush(userId, url.toExternalForm()); } }
如同其他的Spring template,RedisTemplate和StringRedisTemplate允許開發者通過RedisCallback接口直接與Redis對話。這賦予了開發者完整的控制,因為是直接與RedisConnection交互。註意,當使用StringRedisTemplate時,該callback接收的是一個StringRedisConnection實例。
public void useCallback() { redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { Long size = connection.dbSize(); // Can cast to StringRedisConnection if using a StringRedisTemplate ((StringRedisConnection)connection).set("key", "value"); } }); }
序列化器 Serializers
從框架角度來說,存儲在Redis中的數據都是bytes。然而,Redis本身支持不同的類型,更多時候這些是指data存儲的方式,而非其表現形式。由用戶來決定 信息是否需要轉成String或者其他對象。SDR中,用戶的類型和原生類型之間的轉換,是通過RedisSerializer接口來實現的,如名所示,負責序列化過程。SDR提供了多個開箱即用的實現,其中的兩個已經在上面提到了:StringRedisSerializer和JdkSerializationRedisSerializer。然而,用戶也可以使用OxmSerializer來處理Object/XML映射 -- 通過Spring 3OXM支持;或者,使用JacksonJsonRedisSerializer、Jackson2JsonRedisSerializer、或者GenericJackson2JsonRedisSerializer 來實現JSON格式的存儲。註意,存儲格式不僅限於值,它可以用於鍵、值、哈希,沒有任何限制。
Hash映射
Redis中,數據可以使用不同的數據結構來存儲。你已經知道 Jackson2JsonRedisSerializer可以將objects轉成JSON格式。JSON可以使用字符串來存儲。而通過使用Redis Hashes,可以實現一種更復雜的結構化對象的映射。SDR提供了不同的策略來將數據映射成hashes -- 取決於使用情況:- 使用HashOperations和一個序列化器,直接映射。
- 使用Redis Repositories。
- 使用HashMapper和HashOperations。
spring data redis 理解