Spring Data Redis学习

本文是从为知笔记上复制过来的,懒得调整格式了,为知笔记版本是带格式的,内容也比这里全。点这里 为知笔记版本

Spring Data Redis 学习
Version 1.8.4.Release


 
 
 

前言

Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案。咱们(官方)提供了一个 "template" ,这是一个高级别的抽象,来发送和接收消息。你会注意到它与Spring框架对JDBC的支持有些相似。

一、新功能

最近更新中 新的、且 值得一提的功能。

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.二、Spring Data Redis 1.7 新特性

  • 支持RedisCluster。
  • 支持Spring Data Repository抽象。

1.三、Spring Data Redis 1.6 新特性

  • Lettuce Redis驱动,由wg/lettuce切换到mp911de/lettuce。
  • 支持ZRANGEBYLEX.
  • 加强了ZSET的range操做,包括 +inf 、 -inf。
  • RedisCache的性能改进,更早释放链接。
  • Generic Jackson2 RedisSerializer,利用了Jackson的多态反序列化

1.四、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 的概念。

二、为何选择Spring Data Redis?

Spring框架,是引领潮流的全栈Java/JEE应用框架。它提供了一个轻量级容器,一种非侵入式的编程模型 -- 这是由依赖注入、AOP、以及便携的服务抽象开启的。
 
NoSQL存储,提供了传统RDBMS以外的一种选择。
 
SDR框架,使得利用Redis键值存储很是简单,消除了繁复冗余的任务和呆板的代码(指获取链接、释放资源)。

三、要求

  • SDR 1.x要求JDK 6.0及以上,要求Spring框架4.3.9.RELEASE及以上。
  • Redis 2.6.x及以上。

四、开始

学习一个新框架并不简单直接。在本部分,咱们(官方)试图提供一个 咱们认为的 简单易懂的指导,来开始使用SDR。固然,你能够建立适合本身的学习路径,若是能够,请告诉咱们,以便帮助其余人。

4.一、第一步

如同前面所解释的,SDR提供了Spring框架和Redis键值存储的集成。所以,掌握这两个框架很是重要。
虽然本文档的每一部分都提供了相关资源的链接,但最好仍是提早熟悉下。
4.1.一、了解Spring
Spring Data严重依赖Spring框架的核心功能,例如IoC容器、资源抽象、或者AOP。重要的不是掌握Spring的APIs,而是理解它们背后的概念。至少,应该熟悉IoC。简单的说,你对Spring了解的越多,越容易上手SDR。

4.1.二、了解NoSQL和键值存储

略。

4.1.三、尝试案例

在  http://github.com/spring-projects/spring-data-keyvalue-examples上,你能够找到各类各样的键值存储的例子。retwisj。

4.二、须要帮助?

4.2.一、社区帮助

stackoverflow上面,Spring Data 标签。

4.2.二、专业帮助

Pivotal Software, Inc。

4.三、跟随开发

略。

参考文档

五、Redis支持

Spring Data支持的键值存储中包括了Redis。
SDR提供了简单的配置和访问Redis的方式 -- 在Spring应用中。它提供了low-level和high-level抽象 -- 与存储交互,解放了用户。

5.一、Redis要求

Redis 2.6及以上、Java SE 6.0及以上。在connectors方面,Spring Redis集成了Jedis、JRedis(自1.7起已废弃)、SRP(自1.7起已废弃)、以及Lettuce,四个最流行的开源Java Redis库。

5.二、Redis支持高级视图

Redis支持提供了几个组件(按照依赖顺序):
对于大多数人来讲,high-level抽象和支持服务是最佳选择。请注意,用户能够在不一样的层次之间切换 -- 例如,获取low-level链接(甚至native库)来与Redis通讯。

5.三、链接到Redis

使用Redis和Spring的第一步就是经过IoC容器链接到存储。想要实现链接,一个java connector(或者binding)是必需的。不管选择什么库,都只有一套SDR API,叫作 org.springframework.data.redis.connection package,以及RedisConnection和RedisConnectionFactory接口,来获取到Redis的活动链接。

5.3.一、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.二、配置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.三、配置JRedis connector(自1.7起废弃)

略。

5.3.四、配置SRP connector(自1.7起废弃)

略。

5.3.五、配置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.四、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.五、使用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接口),以下:
Table 1. Operational views
Interface Description

Key Type Operationsjava

ValueOperationsnode

Redis string (or value) operationsgit

ListOperationsgithub

Redis list operationsredis

SetOperationsspring

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 GEOADD, GEORADIUS,…)

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.六、聚焦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.七、序列化器 Serializers

从框架角度来讲,存储在Redis中的数据都是bytes。然而,Redis自己支持不一样的类型,更多时候这些是指data存储的方式,而非其表现形式。由用户来决定 信息是否须要转成String或者其余对象。SDR中,用户的类型和原生类型之间的转换,是经过RedisSerializer接口来实现的,如名所示,负责序列化过程。SDR提供了多个开箱即用的实现,其中的两个已经在上面提到了:StringRedisSerializer和JdkSerializationRedisSerializer。然而,用户也可使用OxmSerializer来处理Object/XML映射 -- 经过Spring 3OXM支持;或者,使用JacksonJsonRedisSerializer、Jackson2JsonRedisSerializer、或者GenericJackson2JsonRedisSerializer 来实现JSON格式的存储。
注意,存储格式不只限于值,它能够用于键、值、哈希,没有任何限制。

5.八、Hash映射

Redis中,数据可使用不一样的数据结构来存储。你已经知道 Jackson2JsonRedisSerializer能够将objects转成JSON格式。JSON可使用字符串来存储。而经过使用Redis Hashes,能够实现一种更复杂的结构化对象的映射。SDR提供了不一样的策略来将数据映射成hashes -- 取决于使用状况:
  1. 使用HashOperations和一个序列化器,直接映射。
  2. 使用Redis Repositories。
  3. 使用HashMapper和HashOperations。

5.8.一、Hash mappers   哈希映射器

Hash mappers是将objects与Map<K, V>互相转换的转换器。HashMapper用于Redis Hashes。
多个开箱即用的实现:
  1. BeanUtilsHashMapper,使用Spring的BeanUtils。
  2. ObjectHashMapper,使用Object to Hash Mapping。
  3. 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.二、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;
}

 

Table 2. Normal Mapping
Hash Field Value

firstname

Jon

lastname

Snow

address

{ "city" : "Castle Black", "country" : "The North" }

Table 3. Flat Mapping
Hash Field Value

firstname

Jon

lastname

Snow

address.city

Castle Black

address.country

The North

注意:扁平化,要求全部的property name不能与JSON path冲突。在map中使用点或者括号做为key,或者在实体中做为property name,都不行。若是非要这样作,那获得的hash是没法被映射回对象的。

5.九、Redis 消息/发布订阅

 
5.9.一、发送/发布消息
5.9.二、接收/订阅消息

5.十、Redis事务

5.10.一、@Transactional 支持
5.十一、Pipelining  管道
5.十二、Redis 脚本

5.1三、支持类

5.13.一、对于Spring Cache抽象的支持
六、Redis Cluster
6.一、启用Redis Cluster
6.二、Redis Cluster链接
6.三、使用RedisTemplate 和 ClusterOperations

七、Redis Repositories
7.一、使用
7.二、Object to Hash Mapping
7.三、Keyspaces

7.四、Secondary Indexes

7.4.一、Simple Property Index

7.4.二、Geospatial Index

7.五、Time To Live  存活时间7.六、持久化参考7.七、Persisting Partial Updates7.八、查询和查询方法7.九、运行在Cluster上的Redis Repositories7.十、CDI集成

相关文章
相关标签/搜索