前言

最近工作一直忙的不可开交,小Alan已经很久没有和大家分享知识了,在深圳待了两年多,依然感觉自己还是个小菜鸟,工作中还是会遇到很多自己在短期内无法搞定的事情,每当这个时候总是会感觉到很沮丧,就会心态不好,最近也是,最后不得不把手上的事情转交给比较熟悉或者比较厉害的同事去搞定,或许这是每个开发都会经历的事情吧,小鸟要成长为老鸟,过程还是会比较艰难的。回归正题,今天跟大家一起聊聊Spring集成Redis吧,正好项目也把公司自己封装的一套jedis客户端操作换成了Spring Data Redis,自己过一遍也好在未来啃这个项目打下一些基础。

简单介绍

Redis是一种非关系型的数据库,采用key-value的形式存储数据,这跟我们平时使用的Java自带的哈希Map有很大的相似性,就好像是持久化版的哈希Map。要使用Spring来操作Redis数据库,我们需要用到Spring Data Redis,Spring Data的一个关键特性,面向模板的数据访问,能够在使用Redis的时候,给我们提供很大的帮助。Spring Data Redis包含了多个模板实现, 用来完成Redis数据库的数据存取功能。 为了创建Spring Data Redis的模板, 我们首先需要有一个Redis连接工厂。幸好,Spring Data Redis提供了四个连接工厂供我们选择。

具体实现

maven目前是非常火的项目管理技术,这里我们也使用maven来依赖我们需要的jar包,如果你不会maven,建议你把小Alan写的maven的相关知识过一遍,如图所示:

这里只给大家看图,不提供具体的pom结构代码,如果不会maven的,做为一名Java开发工程师,建议您把maven技术学会,只要随便跟着小Alan写的maven系列的知识过一遍也就对maven的整体使用有一个大概的了解了,并不是很难。

第一步:连接到Redis

Redis连接工厂会生成到Redis数据库服务器的连接。 Spring Data Redis为四种Redis客户端实现提供了连接工厂:

这里我们使用JedisConnectionFactory,如果是在平时的开发中,那就看哪种Redis客户端和连接工厂最适合自己的需求了,不过目前市面上用的最多的应该还是jedis客户端访问redis数据库。

将连接工厂配置为Spring中的bean,下图展示了通过注解的方式配置JedisConnectionFactory bean:

通过默认构造器创建的连接工厂会向localhost上的6379端口创建连接, 并且没有密码。 如果你的Redis服务器运行在其他的主机端口上,在创建连接工厂的时候,可以设置这些属性:

类似地, 如果你的Redis服务器配置为需要客户端认证的话, 那么可以通过调用setPassword()方法来设置密码:

但是这种方式在我们平时的开发中很少用到,在平时的开发中一般还是会采用spring配置文件的实现方式,代码如下:

 # ######## spring redis begin
spring.redis.maxTotal=300
spring.redis.maxIdle=30
spring.redis.maxWaitMillis=4000
spring.redis.timeout=3000
spring.redis.hostName=127.0.0.1
spring.redis.port=6379
#spring.redis.password=
spring.redis.session.timeout=300
# ######## spring redis end
 <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="fileEncoding" value="UTF-8"></property>
<property name="locations">
<list>
<value>classpath:config/*.properties</value>
</list>
</property>
</bean> <!-- JEDIS连接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--新版是maxTotal,旧版是maxActive -->
<property name="maxTotal" value="${spring.redis.maxTotal}" />
<property name="maxIdle" value="${spring.redis.maxIdle}" />
<property name="maxWaitMillis" value="${spring.redis.maxWaitMillis}" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="true" />
</bean> <bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="hostName" value="${spring.redis.hostName}"/>
<property name="port" value="${spring.redis.port}"/>
<!-- <property name="password" value="${redis_pwd}" /> -->
<property name="timeout" value="${spring.redis.timeout}"/>
<property name="usePool" value="true"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>

现在, 我们有了Redis连接工厂, 接下来就可以使用Spring Data Redis模板了。

第二步:使用RedisTemplate

Redis连接工厂会生成到Redis数据库的连接(以RedisConnection的形式)。借助RedisConnection,可以存储和读取数据。例如,我们可以获取连接并使用它来保存一个问候信息,如下所示:

与之类似, 我们还可以使用RedisConnection来获取之前存储的问候信息:

毫无疑问, 这可以正常运行, 但是你难道真的愿意使用字节数组吗?

与其他的Spring Data项目类似, Spring Data Redis以模板的形式提供了较高等级的数据访问方案。 实际上,Spring Data Redis提供了两个模板:

RedisTemplate可以极大地简化Redis数据访问, 能够让我们持久化各种类型的key和value, 并不局限于字节数组。 在认识到key和value通常是String类型之后,StringRedisTemplate 扩展了RedisTemplate , 只关注String类型。

假设我们已经有了RedisConnectionFactory, 那么可以按照如下的方式构建RedisTemplate,xml方式:

 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
</bean>

注解方式案例:

RedisTemplate

StringRedisTemplate

常用的方法:

这些子API中, 包含了很多从Redis中存取数据的方法。

第三步:使用RedisTemplate来操作Redis数据库

我们可以通过Service bean的方式来实现一个Redis数据库操作工具类,在这个工具类中依赖RedisTemplate,然后封装一些常用的操作方法,如图所示设计:

使用简单的值:

获取简单的值:

如果按照给定的key, 无法获得条目的话, 将会返回null。

这里只是用来启发大家的思路,后续的就快速过了,大家要有自己设计代码的能力,不能总是完全照搬别人的代码,那样对自己的能力提升是影响很大,要学会正确的站在巨人的肩膀上。

使用List类型的值:

使用List类型的value与之类似, 只需使用opsForList()方法即可。 例如, 我们可以在一个List类型的条目尾部添加一个值:

通过这种方式, 我们向列表的尾部添加了一个Product, 所使用的这个列表在存储时key为cart。 如果这个key尚未存在列表的话, 将会创建一个。

rightPush()会在列表的尾部添加一个元素, 而leftPush()则会在列表的头部添加一个值:

我们有很多方式从列表中获取元素, 可以通过leftPop()或rightPop()方法从列表中弹出一个元素:

除了从列表中获取值以外, 这两个方法还有一个副作用就是从列表中移除所弹出的元素。 如果你只是想获取值的话(甚至可能要在列表的中间获取) , 那么可以使用range()方法:

range()方法不会从列表中移除任何元素, 但是它会根据指定的key和索引范围, 获取范围内的一个或多个值。
从索引为2的元素到索引为12的元素(不包含) 。 如果范围超出了列表的边界, 那么只会返回索引在范围内的元素。 如果该索引范围内没有元素的话, 将会返回一个空的列表。

在Set上执行操作:

除了操作列表以外, 我们还可以使用opsForSet()操作Set。 最为常用的操作就是向Set中添加一个元素:

在我们有多个Set并填充值之后, 就可以对这些Set进行一些有意思的操作, 如获取其差异、 求交集和求并集:

当然, 我们还可以移除它的元素:

我们甚至还可以随机获取Set中的一个元素:

因为Set没有索引和内部的排序, 因此我们无法精准定位某个点, 然后从Set中获取元素。

绑定到某个key上 :

表格中包含了五个绑定key操作的api,它们能够以绑定key的方式执行操作。 这些子API与其他的API是对应的, 但是关注于某一个给定的key。

为了举例阐述这些子API的用法, 我们假设将Product对象保存到一个list中, 并且key为cart。 在这种场景下, 假设我们想从list的右侧弹出一个元素, 然后在list的尾部新增三个元素。 我们此时可以使用boundListOps()方法所返回的BoundListOperations:

注意, 我们只在一个地方使用了条目的key, 也就是调用boundListOps()的时候。 对返回的BoundListOperations执行的所有操作都会
应用到这个key上。

keyvalue的序列化器介绍

当某个条目保存到Redis key-value存储的时候, key和value都会使用Redis的序列化器(serializer) 进行序列化。 Spring Data Redis提供了多个这样的序列化器, 包括:

这些序列化器都实现了RedisSerializer接口, 如果其中没有符合需求的序列化器, 那么你还可以自行创建。

RedisTemplate会使用JdkSerializationRedisSerializer, 这意味着key和value都会通过Java进行序列
化。 StringRedisTemplate默认会使用StringRedis-Serializer, 这在我们的预料之中, 它实际上就是实现String与byte数组之
间的相互转换。 这些默认的设置适用于很多的场景, 但有时候你可能会发现使用一个不同的序列化器也是很有用处的。

例如, 假设当使用RedisTemplate的时候, 我们希望将Product类型的value序列化为JSON, 而key是String类
型。 RedisTemplate的setKeySerializer()和setValueSerializer()方法就需要如下所示:

在这里, 我们设置RedisTemplate在序列化key的时候, 使用StringRedisSerializer, 并且也设置了在序列化Product的时候, 使
用Jackson2JsonRedisSerializer。

xml配置方式上面已经有所展示。

小结

关系型数据库作为数据持久化领域唯一可选方案的时代已经一去不返了。 现在, 我们有多种不同的数据库, 每一种都代表了不同形式的数据,并提供了适应多种领域模型的功能。 Spring Data能够让我们在Spring应用中使用这些数据库, 并且使用一致的抽象方式访问各种数据库方案。

 

结束语:想要体面生活,又觉得打拼辛苦;想要健康身体,又无法坚持运动。人最失败的,莫过于对自己不负责任,连答应自己的事都办不到,又何必抱怨这个世界都和你作对?人生的道理很简单,你想要什么,就去付出足够的努力。

可爱博主:AlanLee

博客地址:http://www.cnblogs.com/AlanLee

本文出自博客园,欢迎大家加入博客园。

使用Spring操作Redis的key-value数据的更多相关文章

  1. Spring Data Redis入门示例:数据序列化 (四)

    概述 RedisTemplate默认使用的是基于JDK的序列化器,所以存储在Redis的数据如果不经过相应的反序列化,看到的结果是这个样子的: 可以看到,出现了乱码,在程序层面上,不会影响程序的运行, ...

  2. Spring整合redis实现key过期事件监听

    打开redis服务的配置文件   添加notify-keyspace-events Ex  如果是注释了,就取消注释 这个是在以下基础上进行添加的 Spring整合redis:https://www. ...

  3. Java操作Redis存储对象类型数据

    背景描述      关于JAVA去操作Redis时,如何存储一个对象的数据,大家是非常关心的问题,虽然官方提供了存储String,List,Set等等类型,但并不满足我们现在实际应用.存储一个对象是是 ...

  4. 【JAVA】使用 jedis操作redis——连接、存储数据、切库等

    本篇运用Java调用jedis包(jedis在线文档API ),做简单操作实例. 安装jedis 1. 2.9.0 jar 版本下载: jedis-2.9.0.jar 2. 新建项目,添加该驱动包 连 ...

  5. Spring Data操作Redis时,发现key值出现 \xac\xed\x00\x05t\x00\tb

    原文链接:http://blog.csdn.net/yunhaibin/article/details/9001198 最近在研究redis,以及spring data对redis的支持发现了一个奇怪 ...

  6. python 操作redis数据

    python 操作redis 各种类型的数据 # encoding:utf-8 import redis import time def main(): """ redi ...

  7. Spring Data Redis入门示例:Hash操作(七)

    将对象存为Redis中的hash类型,可以有两种方式,将每个对象实例作为一个hash进行存储,则实例的每个属性作为hash的field:同种类型的对象实例存储为一个hash,每个实例分配一个field ...

  8. spring mvc Spring Data Redis RedisTemplate [转]

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

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

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

随机推荐

  1. SpringMVC3.2+Spring3.2+Mybatis3.1(SSM~Demo)

    SpringMVC+Spring+Mybatis 框架搭建 整个Demo的视图结构: JAR: 下载地址:http://download.csdn.net/detail/li1669852599/85 ...

  2. EF基础知识小记六(使用Code First建模自引用关系,常用于系统菜单、文件目录等有层级之分的实体)

    日常开发中,经常会碰到一些自引用的实体,比如系统菜单.目录实体,这类实体往往自己引用自己,所以我们必须学会使用Code First来建立这一类的模型. 以下是自引用表的数据库关系图: ok,下面开始介 ...

  3. JavacProcessingEnvironment类解读

    JavacProcessingEnvironment类的继承体系如下: 其中含有很多内部类,最重要的是迭代注解处理器相关的类,如下:

  4. Mac下TensorFlow安装及环境搭建

    在学习了一段时间台大李宏毅关于deep learning的课程,以及一些其他机器学习的书之后,终于打算开始动手进行一些实践了. 感觉保完研之后散养状态下,学习效率太低了,于是便想白天学习,晚上对白天学 ...

  5. 编写dimgr脚本学到的知识及技巧

    编写dimgr是为了管理手机上的镜像,在此总结下过程中学到的知识及技巧(不讨论具体用法). 参数处理 以往处理脚本参数直接用循环加判断语句,若是脚本只有简单参数,这无疑是简便可行的方法.但当需要处理复 ...

  6. tensorflow summary

    定义summary writer = tf.summary.FileWriter(logdir=self.han_config.log_path, graph=session.graph) 1.sca ...

  7. Linux下串口編程遇到的接收数据错误及原因(0x0d,0x11接收错误)

    摘要:Linux下串口编程遇到的接收数据错误及原因 来源:https://dotblogs.com.tw/k/2012/07/24/73572 近日在调试串口的时候发现,另一设备向我ARM板的串口发送 ...

  8. Git的gitattributes文件详解

    转自:Git的gitattributes文件详解 Git的gitattributes文件是一个文本文件,文件中的一行定义一个路径的若干个属性. 1. gitattributes文件以行为单位设置一个路 ...

  9. s11d27 算法

    s11d27 算法 一.理论 1.1 时间复杂度和空间复杂度的理论: 1)空间复杂度: 是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了, 简单说就是递归集算时通常是反 ...

  10. api.openWin

    打开window 若 window 已存在,则会把该 window 显示到最前面,如果 url 和之前的 url 有变化,或者 reload 为 true 时,页面会刷新,但是该 window 里面已 ...