原文地址:http://www.cnblogs.com/davidwang456/p/4915109.html

  Spring-data-redis为spring-data模块中对redis的支持部分,简称"SDR”,提供了基于jedis客户端与API的高度封装以及spring容器的整合,事实上jedis客户端已经足够简单和轻量级,而spring-data-redis反而具有“过度设计”的嫌疑。

  jedis客户端在编程实施方面存在如下不足:

   1) connection管理缺乏自动化,connection-pool的设计缺少必要的容器支持。

  2) 数据操作需要关注“序列化”/“反序列化”,因为jedis的客户端API接受的数据类型为string和byte,对结构化数据(json,xml,pojo等)操作需要额外的支持。

  3) 事务操作纯粹为硬编码

  4) pub/sub功能,缺乏必要的设计模式支持,对于开发者而言需要关注的太多。

  不过jedis与spring整合,也是非常的简单,参见“jedis连接池实例”.

一.  spring-data-redis针对jedis提供了如下功能

1. 连接池自动管理,提供了一个高度封装的“RedisTemplate”类

2. 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口

  • ValueOperations:简单K-V操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对map类型的数据操作
  • ListOperations:针对list类型的数据操作

3. 提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations:

  • BoundValueOperations
  • BoundSetOperations
  • BoundListOperations
  • BoundSetOperations
  • BoundHashOperations

    4. 将事务操作封装,有容器控制。

5. 针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)

  • JdkSerializationRedisSerializer:POJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略。

    用JdkSerializationRedisSerializer序列化的话,被序列化的对象必须实现Serializable接口。

    在存储内容时,除了属性的内容外还存了其它内容在里面,总长度长,且不容易阅读。

    对于最下面的代码,存到redis里的内容如下:

    redis 127.0.0.1:6379> get users/user1
    "\xac\xed\x00\x05sr\x00!com.oreilly.springdata.redis.User\xb1\x1c \n\xcd\xed%\xd8\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x14t\x00\x05user1"

  • StringRedisSerializer:Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
  • JacksonJsonRedisSerializer:jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】

    如果需要保存对象为json的话推荐使用JacksonJsonRedisSerializer,它不仅可以将对象序列化,

    还可以将对象转换为json字符串并保存到redis中,但需要和jackson配合一起使用。

    用JacksonJsonRedisSerializer序列化的话,被序列化的对象不用实现Serializable接口。

    Jackson是利用反射和getter和setter方法进行读取的,如果不想因为getter和setter方法来影响存储,就要使用注解来定义被序列化的对象。

    Jackson序列化的结果清晰,容易阅读,而且存储字节少,速度快,推荐。

    对于最下面的代码,存到redis里的内容如下:

    redis 127.0.0.1:6379> get json/user1
    "{\"userName\":\"user1\",\"age\":20}"
    redis 127.0.0.1:6379> strlen json/user1
    (integer) 29

  • OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】

针对“序列化和发序列化”中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的策略,原则上,我们可以将数据存储为任何格式以便应用程序存取和解析(其中应用包括app,hadoop等其他工具),不过在设计时仍然不推荐直接使用“JacksonJsonRedisSerializer”和“OxmSerializer”,因为无论是json还是xml,他们本身仍然是String。

如果你的数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer而不是JdkSerializationRedisSerializer。

如果你的数据格式必须为json或者xml,那么在编程级别,在redisTemplate配置中仍然使用StringRedisSerializer,在存储之前或者读取之后,使用“SerializationUtils”工具转换转换成json或者xml,请参见下文实例。

 6. 基于设计模式,和JMS开发思路,将pub/sub的API设计进行了封装,使开发更加便捷。

7.spring-data-redis中,并没有对sharding提供良好的封装,如果你的架构是基于sharding,那么你需要自己去实现,这也是sdr和jedis相比,唯一缺少的特性。

二.简单实例:

1) spring配置:

<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" default-autowire="byName">
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="32"></property>
<property name="maxIdle" value="6"></property>
<property name="maxWait" value="15000"></property>
<property name="minEvictableIdleTimeMillis" value="300000"></property>
<property name="numTestsPerEvictionRun" value="3"></property>
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<property name="whenExhaustedAction" value="1"></property>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="poolConfig" ref="jedisPoolConfig"></property>
<property name="hostName" value="127.0.0.1"></property>
<property name="port" value="6379"></property>
<property name="password" value="0123456"></property>
<property name="timeout" value="15000"></property>
<property name="usePool" value="true"></property>
</bean>
<bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
</beans>

2) 程序实例:

public class SpringDataRedisTestMain {

    /**
* @param args
*/
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-redis-beans.xml");
RedisTemplate redisTemplate = (RedisTemplate)context.getBean("jedisTemplate");
//其中key采取了StringRedisSerializer
//其中value采取JdkSerializationRedisSerializer
ValueOperations<String, User> valueOper = redisTemplate.opsForValue();
User u1 = new User("zhangsan",12);
User u2 = new User("lisi",25);
valueOper.set("u:u1", u1);
valueOper.set("u:u2", u2);
System.out.println(valueOper.get("u:u1").getName());
System.out.println(valueOper.get("u:u2").getName());
} /**
* 如果使用jdk序列化方式,bean必须实现Serializable,且提供getter/setter方法
* @author qing
*
*/
static class User implements Serializable{ /**
*
*/
private static final long serialVersionUID = -3766780183428993793L;
private String name;
private Date created;
private int age;
public User(){}
public User(String name,int age){
this.name = name;
this.age = age;
this.created = new Date();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} } }

3) RedisTemplate:

如果你使用过jedisPool连接池,在数据操作之前,你需要pool.getResource()即从连接池中获取“链接资源”(Jedis),在操作之后,你需要(必须)调用pool.returnResource()将资源归还个连接池。但是,spring-data-redis中,我们似乎并没有直接操作pool,那么spring是如何做到pool管理的呢??一句话:spring的“看门绝技”--callback。

  • public <T> T execute(RedisCallback<T> action):这个方法是redisTemplate中执行操作的底层方法,任何基于redisTemplate之上的调用(比如,valueOperations)最终都会被封装成RedisCallback,redisTemplate在execute方法中将会直接使用jedis客户端API进行与server通信,而且在如果使用了连接池,则会在操作之后执行returnSource。

其他实例请参考如下链接:

1) serializer实例

2) operation实例

3) pub/sub实例

Spring-data-redis:特性与实例(转载)的更多相关文章

  1. spring mvc Spring Data Redis RedisTemplate [转]

    http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...

  2. Spring Data Redis 让 NoSQL 快如闪电(2)

    [编者按]本文作者为 Xinyu Liu,文章的第一部分重点概述了 Redis 方方面面的特性.在第二部分,将介绍详细的用例.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 把 Redis ...

  3. Spring Data Redis 让 NoSQL 快如闪电 (1)

    [编者按]本文作者为 Xinyu Liu,详细介绍了 Redis 的特性,并辅之以丰富的用例.在本文的第一部分,将重点概述 Redis 的方方面面.文章系国内 ITOM 管理平台 OneAPM 编译呈 ...

  4. Spring Data Redis学习

    本文是从为知笔记上复制过来的,懒得调整格式了,为知笔记版本是带格式的,内容也比这里全.点这里 为知笔记版本 Spring Data Redis 学习 Version 1.8.4.Release 前言 ...

  5. Redis与Spring Data Redis

    1.Redis概述 1.1介绍 官网:https://redis.io/ Redis是一个开源的使用ANSIC语言编写.支持网络.可基于内存 亦可持久化的日志型.Key-Value型的高性能数据库. ...

  6. Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解

    一.概念简介: Redis: Redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写,详细的信息在Redis官网上面有,因为我自己通过google等各种渠道去学习Redis, ...

  7. spring data redis 理解

    前言 Spring Data Redis project,应用了Spring概念来开发使用键值形式的数据存储的解决方案.我们(官方)提供了一个 "template" ,这是一个高级 ...

  8. Spring Data Redis 详解及实战一文搞定

    SDR - Spring Data Redis的简称. Spring Data Redis提供了从Spring应用程序轻松配置和访问Redis的功能.它提供了与商店互动的低级别和高级别抽象,使用户免受 ...

  9. spring data redis使用1——连接的创建

    spring data redis集成了几个Redis客户端框架,Jedis , JRedis (Deprecated since 1.7), SRP (Deprecated since 1.7) a ...

  10. 关于在项目中使用spring data redis与jedis的选择

    项目中需要用到redis,主要用来作为缓存,redis的客户端有两种实现方式,一是可以直接调用jedis来实现,二是可以使用spring data redis,通过spring的封装来调用. 应该使用 ...

随机推荐

  1. OpenSSL使用3(基本原理及生成过程)(转)

    1. 基本原理 OpenSSL初接触的人恐怕最难的在于先理解各种概念 公钥/私钥/签名/验证签名/加密/解密/非对称加密 我们一般的加密是用一个密码加密文件,然后解密也用同样的密码.这很好理解,这个是 ...

  2. Python操作sqlite数据库小节

    学习了Python操作sqlite数据库,做一个小结,以备后用. import sqlite3import os# 进行数据库操作时,主要是参数如何传输try:# 链接数据库conn=sqlite3. ...

  3. 在Android中实现阴影效果

    在Android L推出后,Google提出了全新的设计语言:材质设计.其中很重要的一点就是阴影效果的使用,你可以为每一个View设置一个elevation值,相当于除了x.y之外的z值,z值决定了阴 ...

  4. ylb: SQL表的高级查询-子查询

    ylbtech-SQL Server: SQL Server- SQL表的高级查询-子查询 SQL Server 表的高级查询-子查询. 1,ylb:表的高级查询-子查询返回顶部 --======== ...

  5. 对数据进行GZIP压缩和解压

    public class GzipUtils { /** * 对字符串进行gzip压缩 * @param data * @return * @throws IOException */ public ...

  6. nginx/iptables动态IP黑白名单实现方案

    nginx/iptables动态IP黑白名单实现方案 一.手动封IP步骤 1.Nginx手动封IP 1.获取各个IP访问次数 awk '{print $1}' nginx.access.log |so ...

  7. 2016.10.10 Failed to start component [StandardService[Catalina]]

    Failed to start component [StandardService[Catalina]] 错误原因:有数据残留,点击clean(见下图)     解决办法: 右键点击servers下 ...

  8. remove-duplicates-from-sorted-array-ii——去除重复

    Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...

  9. mixare的measureText方法在频繁调用时抛出“referencetable overflow max 1024”的解决方式

    这几天在搞基于位置的AR应用,採用了github上两款开源项目: mixare android-argument-reality-framework 这两个项目实现机制大致同样.我选取的是androi ...

  10. Linux是怎么启动的(整理)

    昨天笔试考了一道关于linux系统启动的过程,当时没答上来,现在整理出来(其实并不复杂). 按下电源按钮的直到欢迎页出来之后,linux总共做的事可以分为五步来完成. 1.  BIOS加电自检: 加电 ...