原文地址: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. 由ASIHttpRequest里的block引发的思考

    项目发http请求,现在一般的都是用的第三方开源库,当然发异步请求时我们也会写几个回调函数来进行请求返回时的处理.不过前段时间看一个朋友写的代码,里面很用block简单的实现了回调相关的部分.比如: ...

  2. VS2010 MFC中 Date Time Picker控件的使用

    1. 在工具箱中找到Date Time Picker控件,然后拖放到对话框上. 2. 在其属性中按自己的需求做一些设置. Format 属性:Long Date (长日期):****年**月**日 S ...

  3. EasyMvc入门教程-高级控件说明(20)表格控件

    表单与表格是信息化系统里很常见的控件,EasyMvc提供了简单的数据绑定方式(基于Json),看下面的示例:  准备的接口地址代码如下:(该接口适用以下所有例子) public IActionResu ...

  4. maven管理整理

    maven管理整理 学习了:https://www.imooc.com/learn/443 mvn -v 版本 compile 编译 test 测试 package 打包 clean 删除 insta ...

  5. linux中grep注意

    grep -l 只输出文件名: -h 只输出匹配的行 不输出文件名: -c 之处匹配内容的行数: -n 将结果输出的同时,也输出改行的行号: -c 统计查到的总行数: -i 忽略大小写: grep ' ...

  6. windows的iis做后门,隐藏访问,无日志

    windows下的iis5/iis6做后门,隐藏访问,不留访问记录或者不留日志 好不容易攻下一台Windows2000/2003 IIS服务器,你一定会想,怎样才能长期占有这个“肉鸡”呢?聪明的你肯定 ...

  7. Linux 的计划任务(运维基础|可用于提权)

    Linux操作系统定时任务系统 Cron 入门 先写笔记: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 crontab -l //列出某个用户 ...

  8. 微信小程序 - 对象转换成对象数组

    后端传过来的一个个对象 {1,2,3,4},{1,3,5,},{1,3,5} 我们应该转化为数组对象 [{},{},{},{}]  ,最后通过wx:for遍历到页面 示例图:

  9. 设计模式之MVC设计模式初阶

    MVC M:Model(数据) V:View(界面) C:Control(控制) 1⃣️Control可以直接访问View和Model 2⃣️View不可以拥有Control和Model属性,降低耦合 ...

  10. Easy UI form表单提交 IE浏览器不执行success ,以及 datagrid 展示过慢

    最近在做一个Easy ui的项目 发现了一些问题,在这里总结下 1.表单提交,后端代码 public ActionResult Save(Request model) { ResultInfo _in ...