步骤1:Spring 对 Redis的支持步骤2:先运行,看到效果,再学习步骤3:模仿和排错步骤4:redis.properties步骤5:applicationContext.xml步骤6:RedisUtil 步骤7:TestRedis
步骤 1 : Spring 对 Redis的支持
Spring 对Redis的操作也有较好的支持,本例讲解如何用Spring 来访问 Redis步骤 2 : 先运行,看到效果,再学习
老规矩,先下载下载区(点击进入)的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
运行 TestRedis ,可以看到如图所示的效果,这些值都是通过spring 放进 Redis,然后又取出来的测试
![01711df03bb285958a2861c2555fa74d.png](https://i-blog.csdnimg.cn/blog_migrate/a17fdaa428d3a364d856dc624bf323d4.jpeg)
步骤 3 : 模仿和排错
在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。
推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程步骤 4 : redis.properties
这里指定连接 Redis 服务器的相关信息#ip地址
redis.hostName=127.0.0.1
#端口号
redis.port=6379
#如果有密码
redis.password=
#客户端超时时间单位是毫秒 默认是2000
redis.timeout=2000
#最大空闲数
redis.maxIdle=10
#连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
redis.maxActive=10
#控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
redis.maxTotal=10
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#连接的最小空闲时间 默认1800000毫秒(30分钟)
redis.minEvictableIdleTimeMillis=300000
#每次释放连接的最大数目,默认3
redis.numTestsPerEvictionRun=1024
#逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
redis.timeBetweenEvictionRunsMillis=30000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=false
#在空闲时检查有效性, 默认false
redis.testWhileIdle=false
步骤 5 : applicationContext.xml
配置连接池,连接工厂等,以上都是为了RedisTemplate 服务,这个类就提供常用的访问 Redis的方法。
然后又把这个 RedisTemplate 类的实例,注入到 RedisUtil 工具类里,方便调用<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder
location="classpath:*.properties"
/>
<!-- redis连接池配置-->
<bean
id="jedisPoolConfig"
class="redis.clients.jedis.JedisPoolConfig"
>
<!--最大空闲数-->
<property
name="maxIdle"
value="${redis.maxIdle}"
/>
<!--连接池的最大数据库连接数 -->
<property
name="maxTotal"
value="${redis.maxTotal}"
/>
<!--最大建立连接等待时间-->
<property
name="maxWaitMillis"
value="${redis.maxWaitMillis}"
/>
<!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
<property
name="minEvictableIdleTimeMillis"
value="${redis.minEvictableIdleTimeMillis}"/>
<!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
<property
name="numTestsPerEvictionRun"
value="${redis.numTestsPerEvictionRun}"
/>
<!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
<property
name="timeBetweenEvictionRunsMillis"value="${redis.timeBetweenEvictionRunsMillis}"
/>
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property
name="testOnBorrow"
value="${redis.testOnBorrow}"
/>
<!--在空闲时检查有效性, 默认false -->
<property
name="testWhileIdle"
value="${redis.testWhileIdle}"
/>
</bean
>
<!--redis连接工厂 -->
<bean
id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
destroy-method="destroy">
<property
name="poolConfig"
ref="jedisPoolConfig"></property>
<!--IP地址 -->
<property
name="hostName"
value="${redis.hostName}"></property>
<!--端口号 -->
<property
name="port"
value="${redis.port}"></property>
<!--如果Redis设置有密码 -->
<property
name="password"
value="${redis.password}"
/>
<!--客户端超时时间单位是毫秒 -->
<property
name="timeout"
value="${redis.timeout}"></property>
</bean>
<!--redis操作模版,使用该对象可以操作redis -->
<bean
id="redisTemplate"
class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-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>
<property
name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property
name="hashValueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean
>
<!--自定义redis工具类,在需要缓存的地方注入此类 -->
<bean
id="redisUtil"
class="com.how2java.RedisUtil">
<property
name="redisTemplate"
ref="redisTemplate"
/>
</bean>
</beans>
步骤 6 : RedisUtil
RedisUtil 工具类,封装了 RedisTemplate 这个类,以提供更为便利的 对于 Redis 的访问package
com.how2java;
import
java.util.List;
import
java.util.Map;
import
java.util.Set;
import
java.util.concurrent.TimeUnit;
import
org.springframework.data.redis.core.RedisTemplate;
import
org.springframework.util.CollectionUtils;
/**
* 基于spring和redis的redisTemplate工具类
* 针对所有的hash 都是以h开头的方法
* 针对所有的Set 都是以s开头的方法 不含通用方法
* 针对所有的List 都是以l开头的方法
*/
public
class
RedisUtil {
private
RedisTemplate<String, Object> redisTemplate;
public
void
setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public
boolean
expire(String key,long
time){
try
{
if(time>0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public
long
getExpire(String key){
return
redisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public
boolean
hasKey(String key){
try
{
return
redisTemplate.hasKey(key);
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public
void
del(String ... key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public
Object get(String key){
return
key==null?null:redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public
boolean
set(String key,Object value) {
try
{
redisTemplate.opsForValue().set(key, value);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public
boolean
set(String key,Object value,long
time){
try
{
if(time>0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
set(key, value);
}
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 递增
* @param key 键
* @param by 要增加几(大于0)
* @return
*/
public
long
incr(String key,
long
delta){
if(delta<0){
throw
new
RuntimeException("递增因子必须大于0");
}
return
redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @param by 要减少几(小于0)
* @return
*/
public
long
decr(String key,
long
delta){
if(delta<0){
throw
new
RuntimeException("递减因子必须大于0");
}
return
redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public
Object hget(String key,String item){
return
redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public
Map<Object,Object> hmget(String key){
return
redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public
boolean
hmset(String key, Map<String,Object> map){
try
{
redisTemplate.opsForHash().putAll(key, map);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public
boolean
hmset(String key, Map<String,Object> map,
long
time){
try
{
redisTemplate.opsForHash().putAll(key, map);
if(time>0){
expire(key, time);
}
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public
boolean
hset(String key,String item,Object value) {
try
{
redisTemplate.opsForHash().put(key, item, value);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public
boolean
hset(String key,String item,Object value,long
time) {
try
{
redisTemplate.opsForHash().put(key, item, value);
if(time>0){
expire(key, time);
}
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 删除hash表中的值
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public
void
hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key,item);
}
/**
* 判断hash表中是否有该项的值
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public
boolean
hHasKey(String key, String item){
return
redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public
double
hincr(String key, String item,double
by){
return
redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public
double
hdecr(String key, String item,double
by){
return
redisTemplate.opsForHash().increment(key, item,-by);
}
//============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return
*/
public
Set<Object> sGet(String key){
try
{
return
redisTemplate.opsForSet().members(key);
}
catch
(Exception e) {
e.printStackTrace();
return
null;
}
}
/**
* 根据value从一个set中查询,是否存在
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public
boolean
sHasKey(String key,Object value){
try
{
return
redisTemplate.opsForSet().isMember(key, value);
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 将数据放入set缓存
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public
long
sSet(String key, Object...values) {
try
{
return
redisTemplate.opsForSet().add(key, values);
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
/**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public
long
sSetAndTime(String key,long
time,Object...values) {
try
{
Long count = redisTemplate.opsForSet().add(key, values);
if(time>0) expire(key, time);
return
count;
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return
*/
public
long
sGetSetSize(String key){
try
{
return
redisTemplate.opsForSet().size(key);
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
/**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public
long
setRemove(String key, Object ...values) {
try
{
Long count = redisTemplate.opsForSet().remove(key, values);
return
count;
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
//===============================list=================================
/**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public
List<Object> lGet(String key,long
start,
long
end){
try
{
return
redisTemplate.opsForList().range(key, start, end);
}
catch
(Exception e) {
e.printStackTrace();
return
null;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return
*/
public
long
lGetListSize(String key){
try
{
return
redisTemplate.opsForList().size(key);
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public
Object lGetIndex(String key,long
index){
try
{
return
redisTemplate.opsForList().index(key, index);
}
catch
(Exception e) {
e.printStackTrace();
return
null;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet(String key, Object value) {
try
{
redisTemplate.opsForList().rightPush(key, value);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet(String key, Object value,
long
time) {
try
{
redisTemplate.opsForList().rightPush(key, value);
if
(time >
0) expire(key, time);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet(String key, List<Object> value) {
try
{
redisTemplate.opsForList().rightPushAll(key, value);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public
boolean
lSet(String key, List<Object> value,
long
time) {
try
{
redisTemplate.opsForList().rightPushAll(key, value);
if
(time >
0) expire(key, time);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public
boolean
lUpdateIndex(String key,
long
index,Object value) {
try
{
redisTemplate.opsForList().set(key, index, value);
return
true;
}
catch
(Exception e) {
e.printStackTrace();
return
false;
}
}
/**
* 移除N个值为value
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public
long
lRemove(String key,long
count,Object value) {
try
{
Long remove = redisTemplate.opsForList().remove(key, count, value);
return
remove;
}
catch
(Exception e) {
e.printStackTrace();
return
0;
}
}
}
步骤 7 : TestRedis
测试类,做了一些简单的增加,删除,获取的例子,来测试对 Redis的访问。package
com.how2java;
import
java.util.HashMap;
import
java.util.Map;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public
class
TestRedis {
public
static
void
main(String[] args)
throws
Exception {
ApplicationContext context=newClassPathXmlApplicationContext("classpath:applicationContext.xml");
RedisUtil redisUtil=(RedisUtil) context.getBean("redisUtil");
//=====================testString======================
redisUtil.set("name",
"how2java");
System.out.println(redisUtil.get("name"));
redisUtil.del("name");
System.out.println(redisUtil.get("name"));
//=====================testNumber======================
long
incr = redisUtil.incr("number",
1);
System.out.println(incr);
incr =redisUtil.incr("number",
1);
System.out.println(incr);
//=====================testMap======================
Map<String,Object> map=new
HashMap<>();
map.put("name",
"meepo");
map.put("pwd",
"password");
redisUtil.hmset("user", map);
System.out.println(redisUtil.hget("user","name"));
}
}
更多内容,点击了解: https://how2j.cn/k/redis/redis-sping-data-redis/1719.html