Redis及Spring-Data-Redis入门学习
2019独角兽企业重金招聘Python工程师标准>>>
继上一篇Solr和Spring Data Solr学习,我们思考一个问题,使用Solr的目的是什么?肯定是为了加快服务器的相应速度。因为即使不适用Solr,通过请求数据库我们一样能完成搜索功能,但是这样会给服务器造成很大的压力。
而Solr仅仅是在搜索功能中用到了,但是大量请求的数据不仅仅出现在搜索中,比如用户的登录信息,虽然数据量很小,但是整个项目每刷新一次页面都要请求一次用户登录的Token信息,也会拖慢服务器的响应速度。我们通常有两中解决方式:1.数据缓存;2.网页静态化。
其实我们在Shiro实现用户-角色-权限管理系统中已经用到了缓存技术,今天我们了解一下Redis缓存技术。
项目开源地址: Github
安装Redis
Redis是一款开源的Key-Value数据库。首先我们要去 官网 下载Redis,由于笔者使用的是MacOS系统,和Windows系统有所不同。
安装过程不再叙述,这里提供两个教程:
Windows: Redis安装教程
MacOS&Linux: Redis安装教程
<br/>
启动Redis
redis-server
redis-server &
建议使用第二个命令,用第二个命令启动了redis server后能继续输入命令,使用第一个命令则不行。
如果终端中显示如下logo表示redis启动成功:
<br/>
操纵Redis
上面仅仅是启动了Redis Server,但Redis是一种Key-Value型数据库,也包含了一些查询数据库的命令,操作redis命令的入口就是: redis/bin/redis-cli
./bin/redis-cliredis-cli
- 查看当前(db0)数据库中所有的key值:
keys *
- 清空当前数据库中所有的数据:
flushall
更多的Redis命令可以参看:redis中文文档
<br/>
Spring Data Redis
之前学习Solr的时候用到了Spring Data Solr,现在学习Redis,Spring提供了Spring Data Redis用来实现通过配置文件的方式访问redis服务。Spring Data Redis对Redis底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate
提供了redis各种操作、异常处理及序列化。
Jedis
Jedis是Redis官方推出的一款面向Java的客户端,提供了很多借口供Java语言调用。
Spring Data Redis针对Jedis提供了如下功能:
- 1.连接池自动管理,提供了一个高度封住的
RedisTemplate
类。 - 2.针对jedis客户端中大量api进行归类封装,将同一类型操作封装为operation接口: ValueOperations: 简单的K-V操作 SetOperations: set类型数据操作 ZSetOperations: zset类型数据操作 HashOperations: 针对Map类型的数据操作 ListOperations: 针对List类型的数据操作
准备
导入依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version>
</dependency>
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.2.RELEASE</version>
</dependency>
创建redis-config.properties
redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
解释
redis.host
是安装redis server的客户端IP地址,如果安装在本机上就是127.0.0.1,如果安装在服务器上请修改为服务器的IP地址。redis.port
是redis server的默认端口,你安装了redis,就默认使用这个端口号。redis.pass
是访问redis server的密码,一般我们不设置。redis.database=0
代表使用的是redis默认提供的db0这个数据库。redis-maxIdle
是redis server的最大空闲数。redis-maxWait
是连接redis时的最大等待毫秒数。redis-testOnBorrow
在提取一个redis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的。
创建spring-redis.xml
<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:other/*.properties"/><!-- redis 相关配置 --><bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"><!-- 最大空闲数 --><property name="maxIdle" value="${redis.maxIdle}"/><!-- 连接时最大的等待时间(毫秒) --><property name="maxWaitMillis" value="${redis.maxWait}"/><!-- 在提取一个jedis实例时,是否提前进行验证操作;如果为true,则得到的jedis实例均是可用的 --><property name="testOnBorrow" value="${redis.testOnBorrow}"/></bean><bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"><property name="hostName" value="${redis.host}"/><property name="port" value="${redis.port}"/><property name="password" value="${redis.pass}"/><property name="poolConfig" ref="poolConfig"/></bean><bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="jedisConnectionFactory"/></bean>
</bean>
实例
本实例源码:Github
首先加载配置文件spring-redis.xml
,注入RedisTemplate
模板类:
@Autowired
private RedisTemplate redisTemplate;
值类型
RedisTemplate
提供的很多操作redis数据库的方法都是boundxxOps
这种。
添加
@Test
public void setValue(){redisTemplate.boundValueOps("name").set("tycoding");
}
如果配置都正常的情况下,运行此方法就能向db0数据库中添加一条key为name
的记录;那么我们在redis命令行中查看所有的key:
奇怪,我添加的key明明是name
,为什么查出来的确实一堆乱码值呢?我们再使用redis命令行单独添加一条记录:
set testK testV
此时我们又发现,使用redis原生命令添加的数据是不会乱码的;那么就肯定是Spring Data Redis的原因了。经查询是因为redisTemplate模板类在操作redis序列化的原因,我们要手动配置序列化方式为:StringRedisSerializer
修改之前创建的spring-redis.xml
配置文件:
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="jedisConnectionFactory"/><!-- 序列化策略 推荐使用StringRedisSerializer --><property name="keySerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="valueSerializer"><bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/></property><property name="hashKeySerializer"><bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/></property><property name="hashValueSerializer"><bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/></property>
</bean>
再次添加数据
查询
@Test
public void getValue(){Object name = redisTemplate.boundValueOps("name").get();System.out.println(name);
}
删除
@Test
public void deleteValue(){redisTemplate.delete("name");
}
Set类型
添加
@Test
public void setValueBySet(){redisTemplate.boundSetOps("nameset").add("tycoding");
}
查询
@Test
public void getValueBySet(){Set nameset = redisTemplate.boundSetOps("nameset").members();System.out.println(nameset);
}
删除Set中某一个值
@Test
public void deleteValueBySet(){redisTemplate.boundSetOps("nameset").remove("涂陌");
}
删除整个Set
@Test
public void deleteAllValueByset(){redisTemplate.delete("nameset");
}
List类型
右压栈
右压栈,后添加的对象排在后边
@Test
public void setRightValueByList(){redisTemplate.boundListOps("namelist").rightPush("tycoding");redisTemplate.boundListOps("namelist").rightPush("涂陌");
}
显示右压栈集合
@Test
public void getRightValueByListI(){List namelist = redisTemplate.boundListOps("namelist").range(0, 10);System.out.println(namelist);
}
左压栈
左压栈,后添加的对象排在前面
@Testpublic void setLeftValueByList(){redisTemplate.boundListOps("namelist2").leftPush("tycoding");redisTemplate.boundListOps("namelist2").leftPush("涂陌");}
显示左压栈的集合:
@Testpublic void getLeftValueByList(){List name2 = redisTemplate.boundListOps("namelist2").range(0, 10);System.out.println(name2);}
根据索引查询集合中的元素
@Testpublic void searchByIndex(){Object namelist = redisTemplate.boundListOps("namelist").index(1);System.out.println(namelist);}
Hash类型
添加
@Testpublic void setValueByHash(){redisTemplate.boundHashOps("namehash").put("a","tycoding");}
提取所有的KEY
@Testpublic void getKeysByHash(){Set namehash = redisTemplate.boundHashOps("namehash").keys();System.out.println(namehash);}
提取所有的VALUE
@Testpublic void getValuesByHash(){List namehash = redisTemplate.boundHashOps("namehash").values();System.out.println(namehash);}
根据KEY取值
@Testpublic void getValueByHash(){Object o = redisTemplate.boundHashOps("namehash").get("a");System.out.println(o);}
根据KEY移除值
@Testpublic void deleteValueByHash(){redisTemplate.boundHashOps("namehash").delete("a");}
<br/>
测试
上面说了一大堆,没有实际的测试,着实不清楚Redis究竟效果如何,是不是真的提高了访问速度?
下面我们以查询数据库所有值的功能来看一下使用Redis缓存和未使用缓存直接查询数据库所用时间。
本例源码地址:Github
未使用Redis缓存,直接请求数据库
public List<Goods> findAll() {return goodsMapper.findAll();
}
使用了Redis缓存
首先通过boundHashOps
获取Redis数据库中是否存在KEY为all
的数据,有的话就返回;没有的话就查询数据库并将查询到的数据添加到Redis数据库中,且KEY为all
public List<Goods> findAll() {List<Goods> contentList = (List<Goods>) redisTemplate.boundHashOps("goods").get("all");if (contentList == null) {//说明缓存中没有数据System.out.println("从数据库中读取数据放入redis...");contentList = goodsMapper.findAll();redisTemplate.boundHashOps("goods").put("all", contentList); //存入redis中} else {System.out.println("从缓存中读取数据...");}// return goodsMapper.findAll();return contentList;
}
TestTime.java
@Test
public void run1() {Long startTime = System.currentTimeMillis(); //开始时间goodsMapper.findAll();Long endTime = System.currentTimeMillis(); //结束时间System.out.println("查询数据库--共耗时:" + (endTime - startTime) + "毫秒"); //1007毫秒
}@Test
public void run2() {Long startTime = System.currentTimeMillis(); //开始时间goodsService.findAll();Long endTime = System.currentTimeMillis(); //结束时间System.out.println("从redis中读取所有数据,共耗时:" + (endTime - startTime) + "毫秒");
}
在测试类中调用Service层的这两个方法,得到的结果如下:
查询数据库--共耗时:1047毫秒从redis中读取所有数据,共耗时:197毫秒
<br/>
交流
如果大家有兴趣,欢迎大家加入我的Java交流技术群:671017003 ,一起交流学习Java技术。博主目前一直在自学JAVA中,技术有限,如果可以,会尽力给大家提供一些帮助,或是一些学习方法,当然群里的大佬都会积极给新手答疑的。所以,别犹豫,快来加入我们吧!
<br/>
联系
If you have some questions after you see this article, you can contact me or you can find some info by clicking these links.
- [Blog@TyCoding's blog](http://www.tycoding.cn)
- [GitHub@TyCoding](https://github.com/TyCoding)
- [ZhiHu@TyCoding](https://www.zhihu.com/people/tomo-83-82/activities)
转载于:https://my.oschina.net/u/3955926/blog/2208586
Redis及Spring-Data-Redis入门学习相关推荐
- Redis整合Spring Data Redis 开发key和value乱码
Spring整合Redis默认使用的是JDK的序列化 将key,value的序列化改成Spring的就行了. 这种在 可视化界面 看见□□ 其实只是可视化界面显示问题, 真正的数据, 其实并无乱码. ...
- Spring集成redis(Spring Data Redis)
2019独角兽企业重金招聘Python工程师标准>>> 转载地址:http://blog.csdn.net/zhu_tianwei/article/details/44923001 ...
- Spring Data Redis 多源
完整代码:Ciiiiing/springboot_multi_redis 最近需要在同一个项目中访问多个 redis 而 spring data redis 默认是只支持一个数据源的,那就需要我们自己 ...
- Spring认证中国教育管理中心-Spring Data Redis框架教程三
原标题:Spring认证中国教育管理中心-Spring Data Redis框架教程三 10.15.支持类 Packageorg.springframework.data.redis.support提 ...
- Java Spring Data Redis实战与配置参数详解 application.properties...
Redis作为开源分布式高并发缓存,使用范围非常广泛,主流互联网公司几乎都在使用. Java Spring Boot 2.0实战开发Redis缓存可以参考下面的步骤,Redis安装可以直接使用Linu ...
- spring mvc Spring Data Redis RedisTemplate [转]
http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...
- Spring Data Redis 实践
前言 Spring Data Redis是Spring Data大家族的一部分,提供了基于spring应用的简易配置与redis服务访问,它为存储与交互提供了低级(low-level)和高级的(hig ...
- Spring Data Redis 正确使用姿势
课程简介 本课程主要讲解常规 Redis 的写法,Redis 和 Spring 的结合使用,即 Spring Data Redis,以及 Redis 在工作中的正确使用姿势,Redis 和 Sprin ...
- Java Spring Data Redis实战与配置参数详解 application.properties
Redis作为开源分布式高并发缓存,使用范围非常广泛,主流互联网公司几乎都在使用. Java Spring Boot 2.0实战开发Redis缓存可以参考下面的步骤,Redis安装可以直接使用Linu ...
- Spring Data Redis简单使用
项目常见问题思考 在项目中发现:对于首页每天有大量的人访问,对数据库造成很大的访问压力,甚至是瘫痪.那如何解决呢?我们通常的做法有两种:一种是数据缓存.一种是网页静态化.我们今天讨论第一种解决方案.将 ...
最新文章
- 一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现1
- RT-Thread 学习笔记(五)—— RTGUI代码解读
- 2. tz师兄【附面试题总结】
- 软件测试安全性翻译成英语,中文翻译英语测试题-请大家帮我翻译一段关于软件测试的英文(译成中文)#8226; 爱问知识人...
- java对象序列化和反序列化,redis存入和获取对象
- OpenCV-图像金字塔cv::buildPyramid
- RocketMQ 消息队列单机部署及使用
- 记录一次Centos磁盘空间占满的解决办法(转)
- 推荐的Python电子书资源
- 如何在Mac上自定义文件和文件夹图标?看这里
- 【Python】P2440 木材加工
- python中的modify是什么意思_理解Python中的装饰器
- 未找到导入的项目“C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCT
- Latex爬过的坑(2)——I was expecting a ‘,‘ or a ‘}‘
- Java程序员编程学习之路资源合集
- python实验一到五作业+自我总结(待更新)
- GD32450i-EVAL学习笔记 6 - ADC
- 爷青回!用原生 Audio API 实现一个千千静听
- 土壤、病虫害探测等智能识别系统解析
- nginx服务器stream限速配置
热门文章
- vs code 开发企业级python_基于VS Code配置Python开发环境
- 制作css开关,纯css实现开关效果
- win10图标变白纸_超详细的纯净版win10安装教程,手把手教你学会,小白秒变大神!...
- python random函数sample_Python random.seed() random.sample()函数使用
- 联想拯救者r720适合java么_联想拯救者哪个型号好 联想拯救者r720怎么样【详解】...
- php 工厂模式 使用场景,PHP设计模式之工厂模式
- webp转换gif_右键转换文件格式
- python安装第三方库win10_音频处理 windows10下python三方库librosa安装教程
- linux培训机构 网络班,Linux基础教程之网络基础知识与Linux网络配置
- (9) ebj学习: Jpa的增删查改,CURD方法监听和命名查询