本文是从为知笔记上复制过来的,懒得调整格式了,为知笔记版本是带格式的,内容也比这里全。点这里
为知笔记版本 Spring Data Redis 学习 Version 1.8.4.Release
- 1.1、Spring Data Redis 1.8 新特性
- 1.2、Spring Data Redis 1.7 新特性
- 1.3、Spring Data Redis 1.6 新特性
- 1.4、Spring Data Redis 1.5 新特性
介绍
2、为什么选择Spring Data Redis?
3、要求
4、开始
- 5.1、Redis要求
- 5.2、Redis支持高级视图
- 5.3、连接到Redis
- 5.4、Redis Sentinel支持
- 5.5、使用RedisTemplate操作Objects
- 5.6、聚焦String的便捷类
- 5.7、序列化器 Serializers
- 5.8、Hash映射
- 5.9、Redis 消息/发布订阅
- 5.10、Redis事务
- 5.11、Pipelining 管道
- 5.12、Redis 脚本
- 5.13、支持类
- 7.1、使用
- 7.2、Object to Hash Mapping
- 7.3、Keyspaces
- 7.4、Secondary Indexes
- 7.5、Time To Live 存活时间
- 7.6、持久化参考
- 7.7、Persisting Partial Updates
- 7.8、查询和查询方法
- 7.9、运行在Cluster上的Redis Repositories
- 7.10、CDI集成
前言
Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案。我们(官方)提供了一个 “template” ,这是一个高级别的抽象,来发送和接收消息。你会注意到它与Spring框架对JDBC的支持有些类似。
1、新功能
最近更新中 新的、且 值得一提的功能。
1.1、Spring Data Redis 1.8 新特性
- Jedis升级到2.9。
- Lettuce升级到4.2。(注意,Lettuce 4.2要求Java8)。
- 支持Redis GEO 命令。
- 使用Spring Data Repository抽象来支持Geo索引。
- 基于HashMapper实现的MappingRedisConverter。
- 在repository支持中支持PartialUpdate。
- 对于连接到Redis cluster的SSL支持。
- 当使用Jedis时,支持通过ConnectionFactory来设置client name。
1.2、Spring Data Redis 1.7 新特性
- 支持RedisCluster。
- 支持Spring Data Repository抽象。
1.3、Spring Data Redis 1.6 新特性
- Lettuce Redis驱动,由wg/lettuce切换到mp911de/lettuce。
- 支持ZRANGEBYLEX.
- 增强了ZSET的range操作,包括 +inf 、 -inf。
- RedisCache的性能改进,更早释放连接。
- Generic Jackson2 RedisSerializer,利用了Jackson的多态反序列化
1.4、Spring Data Redis 1.5 新特性
- 添加对Redis HyperLogLog命令的支持:PFADD、PFCOUNT、PFMERGE。
- 可配置的JavaType查找,用于基于RedisSerializers的Jackson。
- 基于PropertySource的配置,用于连接到Redis Sentinel。
介绍
本文档是Spring Data Redis (SDR) Support的引用指导。它结束了Key Value模块概念和语法,以及不同存储命名空间的语义。 如果想要key value存储或者Spring的介绍,或者Spring Data例子,请转到 Getting
Started,本文档仅涉及到Spring Data Redis支持,并默认用户熟悉key value存储 以及Spring 的概念。
2、为什么选择Spring Data Redis?
Spring框架,是引领潮流的全栈Java/JEE应用框架。它提供了一个轻量级容器,一种非侵入式的编程模型 — 这是由依赖注入、AOP、以及便携的服务抽象开启的。 NoSQL存储,提供了传统RDBMS之外的一种选择。 SDR框架,使得利用Redis键值存储非常简单,消除了繁复冗余的任务和呆板的代码(指获取连接、释放资源)。
3、要求
- SDR 1.x要求JDK 6.0及以上,要求Spring框架4.3.9.RELEASE及以上。
- Redis 2.6.x及以上。
4、开始
学习一个新框架并不简单直接。在本部分,我们(官方)试图提供一个 我们认为的 简单易懂的指导,来开始使用SDR。当然,你可以创建适合自己的学习路径,如果可以,请告诉我们,以便帮助其他人。
4.1、第一步
如同前面所解释的,SDR提供了Spring框架和Redis键值存储的集成。因此,掌握这两个框架非常重要。
虽然本文档的每一部分都提供了相关资源的连接,但最好还是提前熟悉下。
4.1.1、了解Spring
Spring Data严重依赖Spring框架的核心功能,例如IoC容器、资源抽象、或者AOP。重要的不是掌握Spring的APIs,而是理解它们背后的概念。至少,应该熟悉IoC。简单的说,你对Spring了解的越多,越容易上手SDR。
4.1.2、了解NoSQL和键值存储
略。
4.1.3、尝试案例
在
http://github.com/spring-projects/spring-data-keyvalue-examples上,你可以找到各种各样的键值存储的例子。retwisj。
4.2、需要帮助?
4.2.1、社区帮助
stackoverflow上面,Spring Data 标签。
4.2.2、专业帮助
Pivotal Software, Inc。
4.3、跟随开发
略。
参考文档
5、Redis支持
Spring Data支持的键值存储中包括了Redis。 SDR提供了简单的配置和访问Redis的方式 — 在Spring应用中。它提供了low-level和high-level抽象 — 与存储交互,解放了用户。
5.1、Redis要求
Redis 2.6及以上、Java SE 6.0及以上。在connectors方面,Spring Redis集成了Jedis、JRedis(自1.7起已废弃)、SRP(自1.7起已废弃)、以及Lettuce,四个最流行的开源Java Redis库。
5.2、Redis支持高级视图
Redis支持提供了几个组件(按照依赖顺序): 对于大多数人来说,high-level抽象和支持服务是最佳选择。请注意,用户可以在不同的层次之间切换 — 例如,获取low-level连接(甚至native库)来与Redis通信。
5.3、连接到Redis
使用Redis和Spring的第一步就是通过IoC容器连接到存储。想要实现连接,一个java connector(或者binding)是必需的。无论选择什么库,都只有一套SDR API,叫做 org.springframework.data.redis.connection package,以及RedisConnection和RedisConnectionFactory接口,来获取到Redis的活动连接。
5.3.1、RedisConnection 和 RedisConnectionFactory
RedisConnection 为Redis通信提供了构建模块,会处理与Redis后端的通信。也会将底层连接库的异常自动翻译成Spring的一致的DAO异常层级,因此,用户能够自由切换connectors,而不必修改代码。 注意:对于需要native库API的情况,RedisConnection提供了专有方法getNativeConnection — 会返回原生的、底层的用于通信的对象。
活动的RedicConnection由RedisConnectionFactory创建。另外,该工厂还扮演了PersistenceExceptionTranslator,就是说,一旦声明了,它们会允许用户进行透明的异常翻译。例如,通过使用@Repository和AOP的异常翻译。更多信息,见Spring框架的相关部分。
注意:依赖于底层的配置,工厂会返回一个新的连接 或者 一个现有的连接(使用pool或者shared native connection时)。
使用RedisConnectionFactory最简单的方式,是通过IoC容器配置相应的connector,并将其注入使用类中。
重要:不幸的是,目前,不是所有的connector都支持所有的Redis功能。当调用底层库不支持的API时,会抛出UnsupportedOperationException。这种情况在将来可能被解决,视不同的connector的成熟情况。
5.3.2、配置Jedis connector
Jedis最简单的形式的配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Jedis ConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/> </beans>
生产使用时,用户可能想要调整设置,例如host或者password:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379" /> </beans>
5.3.3、配置JRedis connector(自1.7起废弃)
略。
5.3.4、配置SRP connector(自1.7起废弃)
略。
5.3.5、配置Lettuce connector
Lettuce是SDR支持的第四个开源connector。 它的配置很好猜:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="lettuceConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" p:hostname="server" p:port="6379"/> </beans>
同样,也有一些Lettuce特有的连接参数可以调整。默认,LettuceConnectionFactory创建的所有LettuceConnection都共享相同的线程安全的native 连接 — 针对非阻塞式和非事务性操作而言。 注意:可以设置shareNativeConnection为false,这样每次都使用专有的连接。
注意:LettuceConnectionFactory 也可以为pooling blocking和事务连接配置一个LettucePool,或者,为所有连接配置一个LettucePool — 如果shareNativeConnection设为false的话。
5.4、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。
5.5、使用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. |
一旦配置了,该template就是线程安全的,可被多个实例复用。 开箱即用,RedisTemplate使用一个基于Java的序列化器 用于多数操作。这意味着,该template读/写的任意object会通过Java来序列化/反序列化。 该template的序列化机制可以轻松地修改,该Redis模块提供了几个实现,在org.springframework.data.redis.serializer包中。你也可以不使用序列化器,直接让RedisTemplate使用原生byte数组,只需要将enableDefaultSerializer设为false即可。 注意,该template要求所有的key都不能是null,但value可以是null — 只要底层的序列化器接受;更多内容,请查看每个序列化器的javadoc。 当需要一个特定的template view时,将view声明为依赖,并注入该template中即可:容器会自动执行转换:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <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"/> ... </beans>
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()); } }
5.6、聚焦String的便捷类
鉴于使用java.lang.String来作为key/value 存储到Redis中 非常常见,该Redis模块还提供了RedisConnection和RedisTemplate的两个扩展:StringRedisConnection(以及其DefaultStringRedisConnection实现)和StringRedisTemplate。此外,该template和连接,底层使用了StringRedisSerializer。例如:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <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"/> ... </beans>
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"); } }); }
5.7、序列化器 Serializers
从框架角度来说,存储在Redis中的数据都是bytes。然而,Redis本身支持不同的类型,更多时候这些是指data存储的方式,而非其表现形式。由用户来决定 信息是否需要转成String或者其他对象。SDR中,用户的类型和原生类型之间的转换,是通过RedisSerializer接口来实现的,如名所示,负责序列化过程。SDR提供了多个开箱即用的实现,其中的两个已经在上面提到了:StringRedisSerializer和JdkSerializationRedisSerializer。然而,用户也可以使用OxmSerializer来处理Object/XML映射 — 通过Spring 3OXM支持;或者,使用JacksonJsonRedisSerializer、Jackson2JsonRedisSerializer、或者GenericJackson2JsonRedisSerializer 来实现JSON格式的存储。
注意,存储格式不仅限于值,它可以用于键、值、哈希,没有任何限制。
5.8、Hash映射
Redis中,数据可以使用不同的数据结构来存储。你已经知道 Jackson2JsonRedisSerializer可以将objects转成JSON格式。JSON可以使用字符串来存储。而通过使用Redis Hashes,可以实现一种更复杂的结构化对象的映射。SDR提供了不同的策略来将数据映射成hashes — 取决于使用情况:
- 使用HashOperations和一个序列化器,直接映射。
- 使用Redis Repositories。
- 使用HashMapper和HashOperations。
5.8.1、Hash mappers 哈希映射器
Hash mappers是将objects与Map<K, V>互相转换的转换器。HashMapper用于Redis Hashes。
多个开箱即用的实现:
- BeanUtilsHashMapper,使用Spring的BeanUtils。
- ObjectHashMapper,使用Object to Hash Mapping。
- Jackson2HashMapper,使用FasterXML Jackson。
public class Person { String firstname; String lastname; // … } public class HashMapping { @Autowired HashOperations<String, byte[], byte[]> hashOperations; HashMapper<Object, byte[], byte[]> mapper = new ObjectHashMapper(); public void writeHash(String key, Person person) { Map<byte[], byte[]> mappedHash = mapper.toHash(person); hashOperations.putAll(key, mappedHash); } public Person loadHash(String key) { Map<byte[], byte[]> loadedHash = hashOperations.entries("key"); return (Person) mapper.fromHash(loadedHash); } }
5.8.2、Jackson2HashMapper
Jackson2HashMapper 使用FasterXML Jackson为Redis Hash来映射domain objects。 Jackson2HashMapper 可以映射数据映射高级properties作为Hash字段名字,以及可选的扁平结构。简单类型映射成简单的值。复杂类型(嵌套的objects、集合、maps)会表现成嵌套的JSON。 扁平化 为所有的嵌套properties创建了独立的hash entries,将复杂类型用简单类型表示。
public class Person { String firstname; String lastname; Address address; } public class Address { String city; String country; }
Hash Field | Value |
---|---|
firstname |
|
lastname |
|
address |
|
Hash Field | Value |
---|---|
firstname |
|
lastname |
|
address.city |
|
address.country |
|
注意:扁平化,要求所有的property name不能与JSON path冲突。在map中使用点或者括号作为key,或者在实体中作为property name,都不行。如果非要这样做,那得到的hash是无法被映射回对象的。
5.9、Redis 消息/发布订阅
5.10、Redis事务
5.13、支持类
6.3、使用RedisTemplate 和 ClusterOperations
7、Redis Repositories
7.1、使用
7.2、Object to Hash Mapping
7.3、Keyspaces
7.4、Secondary Indexes
7.4.1、Simple Property Index
7.4.2、Geospatial Index
7.5、Time To Live 存活时间
7.6、持久化参考
7.7、Persisting Partial Updates
7.8、查询和查询方法
7.9、运行在Cluster上的Redis Repositories
7.10、CDI集成