0、导入 maven依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>

1、SDR说明
Spring Data Redis(SDR),是SpringFramework提供的一套简化访问Redis的API,是对Jedis的又一层封装。
SDR集成了Jedis,JRedis,SRP,Lettuce这四种开源的Redis Connector,这些Connector都是针对于Redis的开源Java库。

其中,JRedis和SRP从spring-data-redis1.7开始,就不支持了。

2、RedisTemplate说明

  SDR支持底层次的通过连接器connector连接到Redis,支持高层次的友好的模板类RedisTemplate,RedisTemplate是建立在低级别的connection基础之上。

  RedisConnection接收或返回字节数组需要自身处理连接,比如关闭连接,而RedisTemplate负责处理串行化和反串行化,并且对连接进行管理。

  RedisTemplate是线程安全的,能够用于多个实例中。
  

  RedisTemplate是SDR的一个核心Helper类,该类是一个高级的抽象(对Jedis的又一层封装),它封装了对Redis中的数据的CRUD操作,包含“高级封装”。

---????-->

RedisTemplate默认选择java-based串行化,也可以切换为其它的串行化方式,

或者设置enabledDefaultSerializer为false或者设置串行化器为null,则RedisTemplate用raw byte arrays表示数据。

(1)高级封装(推荐使用)
  高级封装的操作包含:OpsForValue(),OpsForList(),OpsForSet(),OpsForZset(),OpsForHash()等等。
  SDR官方文档中对Redistemplate的介绍:

    the template is in fact the central class of the Redis module due to its rich feature set. The template offers a high-level abstraction for Redis interactions.
  

  通过Redistemplate可以调用ValueOperations和ListOperations等等方法,分别是对Redis命令的高级封装。
  但是ValueOperations等等这些命令最终是要转化成为RedisCallback来执行的。

  也就是说通过使用RedisCallback可以实现更强的功能,

    SDR文档对RedisCallback的介绍:

    RedisTemplate and StringRedisTemplate allow the developer to talk directly to Redis through the RedisCallback interface.

    This gives complete control to the developer as it talks directly to the RedisConnection。

(2)从高级封装获得低级封装的过渡:
  RedisOperations<String, Object> operations = opsForValue.getOperations();

3、RedisConnection提供了“低级封装”。

  低级封装的操作是通过连接到Redis的Connection对象,直接对Redis数据进行操作。
低级封装的核心是:

redisTemplate.execute(

  new RedisCallback(){

    //  .....

  }

)

===========   redis 源码头=============================

RedisTemplate的使用

这个类作为一个模版类,提供了很多快速使用redis的api,而不需要自己来维护连接,事务。

 
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V> {

   private boolean enableTransactionSupport = false;
private boolean exposeConnection = false;
private boolean initialized = false;
private boolean enableDefaultSerializer = true;
private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer(); private RedisSerializer keySerializer = null;
private RedisSerializer valueSerializer = null;
private RedisSerializer hashKeySerializer = null;
private RedisSerializer hashValueSerializer = null;
private RedisSerializer<String> stringSerializer = new StringRedisSerializer(); private ScriptExecutor<K> scriptExecutor; // cache singleton objects (where possible)
private ValueOperations<K, V> valueOps;
private ListOperations<K, V> listOps;
private SetOperations<K, V> setOps;
private ZSetOperations<K, V> zSetOps;
================== 实战 ======================
package cn.test.config.data; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig; import java.util.HashSet;
import java.util.Set; /**
* Created by Miraculous on 15/7/4.
*/
@Configuration
public class RedisConfig { @Value("${test.data.redis.defaultExpiration}")
private Long defaultExpiration;
@Value("${test.redis.master.host}")
private String masterHost;
@Value("${test.redis.master.port}")
private int masterPort;
@Value("${test.redis.master.name}")
private String masterName;
@Value("${test.redis.sentinel1.host}")
private String sentinel1Host;
@Value("${test.redis.sentinel1.port}")
private int sentinel1port;
@Value("${test.redis.sentinel2.host}")
private String sentinel2Host;
@Value("${test.redis.sentinel2.port}")
private int sentinel2port;
@Value("${test.redis.sentinel3.host}")
private String sentinel3Host;
@Value("${test.redis.sentinel3.port}")
private int sentinel3port;   /**
    连接工厂
  */
private RedisConnectionFactory generateDevConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
JedisPoolConfig poolConfig = generatePoolConfig();
factory.setPoolConfig(poolConfig); // 注入连接池
factory.afterPropertiesSet();
return factory;
} private RedisConnectionFactory generateReleaseConnectionFactory() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
RedisNode master = new RedisNode(masterHost, masterPort);
master.setName(masterName);
Set<RedisNode> sentinels = new HashSet<>();
RedisNode sentinel1 = new RedisNode(sentinel1Host, sentinel1port);
RedisNode sentinel2 = new RedisNode(sentinel2Host, sentinel2port);
RedisNode sentinel3 = new RedisNode(sentinel3Host, sentinel3port);
sentinels.add(sentinel1);
sentinels.add(sentinel2);
sentinels.add(sentinel3);
sentinelConfiguration.setMaster(master);
sentinelConfiguration.setSentinels(sentinels);
JedisPoolConfig poolConfig = generatePoolConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(sentinelConfiguration, poolConfig);
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setTimeout(10000);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
factory.afterPropertiesSet();
return factory;
}   /**redis连接池基本配置
    */
private JedisPoolConfig generatePoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(20);
poolConfig.setMaxTotal(300);
poolConfig.setMaxWaitMillis(5000);
poolConfig.setTestOnBorrow(true);
return poolConfig;
} @Bean(name = "redisConnectionFactory")
RedisConnectionFactory factory() {
if (StringUtils.isEmpty(masterName)) {
return generateDevConnectionFactory();
} else {
return generateReleaseConnectionFactory();
}
} @Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer(); template.setEnableTransactionSupport(false); //是否启用事务支持
template.setKeySerializer(stringRedisSerializer); //keySerializer:这个是对key的默认序列化器。默认值是StringSerializer。
template.setHashKeySerializer(stringRedisSerializer);//对hash结构数据的hashkey序列化器,默认值是取自DefaultSerializer的JdkSerializationRedisSerializer。
template.setValueSerializer(jdkSerializationRedisSerializer); //这个是对value的默认序列化器,默认值是取自DefaultSerializer的JdkSerializationRedisSerializer。
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory); // 注入工厂
return template;
} @Bean(name = "stringRedisTemplate")
public RedisTemplate<String, String> stringRedisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, String> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setEnableTransactionSupport(true);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setDefaultSerializer(stringRedisSerializer);
template.setConnectionFactory(factory);
return template;
} @Bean(name = "cacheManager")
public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(defaultExpiration);
// cacheManager.setExpires(ImmutableMap.of("apixDistrictCache", 3600 * 24 * 7L));
cacheManager.setUsePrefix(true);
return cacheManager;
}
}

一、为什么要使用Serializer

  因为redis是以key-value的形式将数据存在内存中,key就是简单的string,key似乎没有长度限制,不过原则上应该尽可能的短小且可读性强,无论是否基于持久存储,key在服务的整个生命周期中都会在内存中,因此减小key的尺寸可以有效的节约内存,同时也能优化key检索的效率。

  value在redis中,存储层面仍然基于string,在逻辑层面,可以是string/set/list/map,不过redis为了性能考虑,使用不同的“encoding”数据结构类型来表示它们。(例如:linkedlist,ziplist等)。

  所以可以理解为,其实redis在存储数据时,都把数据转化成了byte[]数组的形式,那么在存取数据时,需要将数据格式进行转化,那么就要用到序列化和反序列化了,这也就是为什么需要配置Serializer的原因。

二、 RedisTempalte的Serializer

  用过jedis操作的都知道,所有connection的操作方法,都是传入字节数组。那么,将一个对象和字节相互转换,就需要通过序列化和反序列化。

模版方法中,Spring提供了默认的StringSerializer和JdkSerializer,第一个很简单,就是通过String.getBytes()来实现的。而且在Redis中,所有存储的值都是字符串类型的。所以这种方法保存后,通过Redis-cli控制台,是可以清楚的查看到我们保存了什么key,value是什么。

但是对于JdkSerializationRedisSerializer来说,这个序列化方法就是Jdk提供的了。

首先要求我们要被序列化的类继承自Serializable接口,然后通过,然后通过Jdk对象序列化的方法保存。

(注:这个序列化保存的对象,即使是个String类型的,在redis控制台,也是看不出来的,因为它保存了一些对象的类型什么的额外信息)

这么一长串,其实就是一个int类型的123。

三、事物支持

enableTransactionSupport:是否启用事务支持。我们在代码中搜索下用到这个变量的地方,会看到,在调用RedisCallback之前,有一行代码是如果启用事务支持,那么conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport),也就是说,系统自动帮我们拿到了事务中绑定的连接。

可以在一个方法的多次对Redis增删该查中,始终使用同一个连接。但是,即使使用了同样的连接,没有进行connection.multi()和connection.exec(),依然是无法启用事务的。

  我没有仔细的查阅代码,但是可以知道的是,Spring已经对这个,给了我们一个更好的支持:@Transactional

在调用RedisTempalte中的execute()方法的地方,加入这个注解(是spring包下面提供的,不要引用成rt包下的注解),能让这个方法中的所有execute,自动加入multi()以及异常的回滚或者是正常运行时候的提交!

  redis对事务提供支持,包括multi,exec,discard命令,这些命令也能用于RedisTemplate,然后redisTemplate不保证用相同的连接在同一个事务执行所有操作。

  SDR提供SessionCallback接口用于同线程的多操作执行。

四、 RedisSerializer 接口 的是实现子类

public interface RedisSerializer<T> {
}

  其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,

  其中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。

  基本推荐使用JdkSerializationRedisSerializer和StringRedisSerializer,因为其他两个序列化策略使用起来配置很麻烦,

  如果实在有需要序列化成Json和XML格式,可以使用java代码将String转化成相应的Json和XML。

springboot 整合Redis的更多相关文章

  1. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  2. SpringBoot整合Redis及Redis工具类撰写

            SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...

  3. SpringBoot 整合 Redis缓存

    在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. Spr ...

  4. SpringBoot系列十:SpringBoot整合Redis

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ...

  5. springboot整合redis(注解形式)

    springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...

  6. springboot整合redis(简单整理)

    Redis安装与开启 我这里是在windows上练习,所以这里的安装是指在windows上的安装,操作非常简单,点击https://github.com/MicrosoftArchive/redis/ ...

  7. SpringBoot整合redis哨兵主从服务

    前提环境: 主从配置 http://www.cnblogs.com/zwcry/p/9046207.html 哨兵配置 https://www.cnblogs.com/zwcry/p/9134721. ...

  8. springboot整合redis——redisTemplate的使用

    一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...

  9. 九、springboot整合redis二之缓冲配置

    1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSu ...

  10. 三:Springboot整合Redis

    一:springboot整合redis redis版本:3.0.0 运行环境:linux 1.安装redis 1.1安装gcc yum install gcc-c++ 1.2解压redis.3.0.0 ...

随机推荐

  1. SSL/TLS加密传输与数字证书解读

    什么是ssl? secure socket layer(ssl)协议最初由netscape企业发展,现已成为网络用来鉴别网站和网页浏览者身份,以及在浏览器使用者及网页服务器之间进行加密通讯的全球化标准 ...

  2. mysql主从数据库不同步的2种解决方法(转)

    今天发现Mysql的主从数据库没有同步 先上Master库: mysql>show processlist; 查看下进程是否Sleep太多.发现很正常. show master status; ...

  3. [Js/Jquery]table行转列

    摘要 在使用ews调用exhange的收件箱的并在h5页面显示邮件详情的时候,因为返回的每封邮件的内容都是htmlbody,没有textbody.每封邮件又没什么规律,用正则表达式来匹配内容并不合适, ...

  4. protobuf

    1.下载地址:https://code.google.com/p/protobuf/downloads/list 安装 ./configure && make && m ...

  5. 低版本IE浏览器 input元素出现叉叉的情况

    都说是IE10之上的浏览器才有这个问题,恰巧我IE10之上都没有问题,反而是低版本的浏览器出现了这个问题.作为一个凭证,我先放一张图片在这里面. 之前无意中解决过这个问题,如今复现确实是没有解决,网上 ...

  6. 一张图读懂https加密协议

    搭建CA服务器和iis启用https:http://blog.csdn.net/dier4836/article/details/7719532 一张图读懂https加密协议 https是一种加密传输 ...

  7. [机器学习]信息&熵&信息增益

    关于对信息.熵.信息增益是信息论里的概念,是对数据处理的量化,这几个概念主要是在决策树里用到的概念,因为在利用特征来分类的时候会对特征选取顺序的选择,这几个概念比较抽象,我也花了好长时间去理解(自己认 ...

  8. svn搬移到gitlab及使用

    svn是一款非常简便,易用的源代码管理工具,用了这么多年,对它情有独钟.都说习惯最难改,那为何要搬移到gitlab上呢? 喜欢尝试新东西,前提还是git比较强大,svn有的它都有,svn没有的它也有. ...

  9. 微信小程序未来怎么样?听微盟卫晓祥来说说

    微信小程序宣布公测已经一个多月了,开发者一片火热,未来会怎么样?听微盟卫晓祥来说说.微盟移动营销事业部总经理卫晓祥表示,微信小程序最吸引商户的地方在于:一方面小程序作为一种全新的连接用户与服务的方式, ...

  10. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...