redis和spring集成(注解实现,方便,快捷)
Posted Fighter168
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis和spring集成(注解实现,方便,快捷)相关的知识,希望对你有一定的参考价值。
前言:
spring和redis集成有很多方式,看到网上很多都是使用redistemplate自己去做redis 的一些操作,但是对于我们开发来说,肯定是使用越方便越好,于是乎就有了spring的对redis或者memcahe这些换成框架的封装,只需要引入spring的spring-data-redis的jar。
好了,废话不多说,我们开始上代码。
工程目录结构
我们先预览一下这个项目的工程目录结构先:
启动redis
还没安装的redis 的同学可以自己去安装redis,我自己是在window上安装的,其实也不是安装,解压一下就可以使用了,不过需要注意的是它的启动方式,直接点击redis-server启动会直接闪退的,正确的启动方式使用命令【redis-server.exe redis.windows.conf】,详细请参考:Windows 64位下安装Redis详细教程
创建数据库
配置pom文件
pom文件就没什么好说的了,直接贴配置给大家吧
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ylink.com</groupId>
<artifactId>spring-redis-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build />
<properties>
<spring.version>4.2.6.RELEASE</spring.version>
<slf4j.version>1.6.4</slf4j.version>
<logback.version>1.0.0</logback.version>
<junit.version>4.9</junit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>$spring.version</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>$spring.version</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>$junit.version</version>
<scope>test</scope>
</dependency>
<!-- memcached <dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId>
<version>3.0.1</version> </dependency> -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.2</version>
</dependency>
<!-- log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>$slf4j.version</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>$logback.version</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<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>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.7.1.RELEASE</version>
</dependency>
</dependencies>
</project>
配置spring文件
下面是spring-mvc.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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">
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.cn" />
<!-- 引入同文件夹下的redis属性配置文件 -->
<import resource="spring-redis.xml"/>
<import resource="spring-datasource-bonecp.xml"/>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.cn.dao"/>
</bean>
</beans>
下面是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: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:redis-config.properties" />
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven cache-manager="cacheManager" />
<!-- redis 相关配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="$redis.maxIdle" />
<property name="maxWaitMillis" value="$redis.maxWait" />
<property name="testOnBorrow" value="$redis.testOnBorrow" />
</bean>
<bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="$redis.host" p:port="$redis.port" p:password="$redis.pass" p:pool-config-ref="poolConfig"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="JedisConnectionFactory" />
</bean>
<!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<!-- 这里可以配置多个redis -->
<!-- <bean class="com.cn.util.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="default"/>
</bean> -->
<bean class="com.cn.util.RedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="common"/>
<!-- common名称要在类或方法的注解中使用 -->
</bean>
</set>
</property>
</bean>
</beans>
下面是spring-datasource-bonecp.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"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!--用于连接boneCp数据源 -->
<bean id="commonDataSourceConfig" class="com.jolbox.bonecp.BoneCPDataSource" abstract="true" destroy-method="close">
<!-- 每个分区最大的连接数 -->
<property name="maxConnectionsPerPartition" value="100" />
<!-- 每个分区最小的连接数 -->
<property name="minConnectionsPerPartition" value="10" />
<!-- 分区数 ,默认值2,最小1,推荐3-4,视应用而定-->
<property name="partitionCount" value="3" />
<!-- 每次去拿数据库连接的时候一次性要拿几个,默认值:2 -->
<property name="acquireIncrement" value="2" />
<!-- 测试连接有效性的间隔时间,单位分钟
<property name="idleConnectionTestPeriod" value="40" />-->
<!-- 空闲存活时间 分钟
<property name="idleMaxAge" value="10"/>-->
<!-- 连接超时时间 毫秒-->
<property name="connectionTimeout" value="10000"/>
</bean>
<!-- 数据源配置 -->
<bean id="dataSource" parent="commonDataSourceConfig">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/test" />
<property name="username" value="root"/>
<property name="password" value=""/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:cfg.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
编写java类
直接上service,其他的大家可以自己去我上传的源码去下载查看,至于对spring的缓存的注解不太了解怎么使用的,可以参考下这边博客园博主写的博文:Spring Cache使用详解
package com.cn.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.cn.bean.User;
import com.cn.dao.UserDao;
/**
* @类名称: UserServiceImpl
* @类描述:
* @创建人: 1603254
* @创建时间: 2016-12-2 上午11:10:33
*
* @修改人: 1603254
* @操作时间: 2016-12-2 上午11:10:33
* @操作原因:
*
*/
@Service
public class UserServiceImpl implements UserService
@Autowired
private UserDao userDao;
@Cacheable(value="common",key="'id_'+#id")
public User selectByPrimaryKey(Integer id)
System.out.println("======================");
System.out.println("======================");
System.out.println("======================");
return userDao.selectByPrimaryKey(id);
@CachePut(value="common",key="#user.getUserName()")
public void insertSelective(User user)
// userDao.insertSelective(user);
System.out.println("########################");
System.out.println("########################");
System.out.println("########################");
@CacheEvict(value="common",key="'id_'+#id")
public void deleteByPrimaryKey(Integer id)
// userDao.deleteByPrimaryKey(id);
System.out.println("******************************");
System.out.println("******************************");
System.out.println("******************************");
编写mybatis配置文件
下面是cfg.xml配置文件<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- mapping 文件路径配置 -->
<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
<!-- <plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="oracle"/>
该参数默认为false
设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用
和startPage中的pageNum效果一样
<property name="offsetAsPageNum" value="true"/>
该参数默认为false
设置为true时,使用RowBounds分页会进行count查询
<property name="rowBoundsWithCount" value="true"/>
设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果
(相当于没有执行分页查询,但是返回结果仍然是Page类型)
<property name="pageSizeZero" value="true"/>
启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据
<property name="reasonable" value="true"/>
增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值
可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值
<property name="params" value="pageNum=start;pageSize=limit;pageSizeZero=zero;reasonable=heli;count=contsql"/>
</plugin>
</plugins>
-->
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.cn.dao.UserDao" >
<resultMap id="resultMap" type="com.cn.bean.User" >
<result column="id" property="id" jdbcType="CHAR" />
<result column="name" property="name" jdbcType="CHAR" />
</resultMap>
<!--添加-->
<insert id="insertSelective" parameterType="com.cn.bean.User">
insert into user(id,name) values(#id,jdbcType=CHAR,#name,jdbcType=VARCHAR)
</insert>
<!--查询-->
<select id="selectByPrimaryKey" resultMap="resultMap">
select * from user where id=#id
</select>
<!--删除-->
<select id="deleteByPrimaryKey" resultMap="resultMap">
delete from user where id=#id
</select>
</mapper>
配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app id="WebApp_ID">
<display-name>spring-redis-test</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
</web-app>
编写测试用例
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import com.cn.bean.User;
import com.cn.service.UserService;
@ContextConfiguration(locations="classpath:spring-mvc.xml")
public class Test extends AbstractJUnit4SpringContextTests
@Autowired
private UserService userService;
@org.junit.Test
public void add()
User user=new User();
user.setName("wen");
user.setId("1");
userService.insertSelective(user);
@org.junit.Test
public void query()
User user=userService.selectByPrimaryKey(1);
System.out.println(user.toString());
上面我是这样执行校验的: 1)先把数据库的操作打开,插入一条数据,插入的时候,数据库会插入一条数据,redis里面也会有一条数据。 2)然后执行查询的测试用例,第一次查询会将数据库的数据查到redis,然后第二次直接从redis里面去查询,你可以把数据库的数据删掉,结果显示是可以从redis里面查询出来
上面代码我都测试过,无措执行,部分缺少的java类,可以直接下载demo查看,有问题大家可以提出来讨论一下,谢谢~
源代码下载
下载地址是:spring集成redis源码+表结构
其实说实话,用起来还是蛮简单的,而且方便,快捷,真正想要了解深入一点的话,还是建议有时间去看看源代码。
后面大家评论说RedisCache类没写给出来,下面给一下(链接里面的demo 有Override 注解删除就可以使用了):
package com.cn.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
public class RedisCache implements Cache
private RedisTemplate<String, Object> redisTemplate;
private String name;
public RedisTemplate<String, Object> getRedisTemplate()
return redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate)
this.redisTemplate = redisTemplate;
public void setName(String name)
this.name = name;
public String getName()
// TODO Auto-generated method stub
return this.name;
public Object getNativeCache()
// TODO Auto-generated method stub
return this.redisTemplate;
public ValueWrapper get(Object key)
// TODO Auto-generated method stub
System.out.println("get key");
final String keyf = key.toString();
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>()
public Object doInRedis(RedisConnection connection)
throws DataAccessException
byte[] key = keyf.getBytes();
byte[] value = connection.get(key);
if (value == null)
return null;
return toObject(value);
);
return (object != null ? new SimpleValueWrapper(object) : null);
public void put(Object key, Object value)
// TODO Auto-generated method stub
System.out.println("put key");
final String keyf = key.toString();
final Object valuef = value;
final long liveTime = 86400;
redisTemplate.execute(new RedisCallback<Long>()
public Long doInRedis(RedisConnection connection)
throws DataAccessException
byte[] keyb = keyf.getBytes();
byte[] valueb = toByteArray(valuef);
connection.set(keyb, valueb);
if (liveTime > 0)
connection.expire(keyb, liveTime);
return 1L;
);
private byte[] toByteArray(Object obj)
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray();
oos.close();
bos.close();
catch (IOException ex)
ex.printStackTrace();
return bytes;
private Object toObject(byte[] bytes)
Object obj = null;
try
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
obj = ois.readObject();
ois.close();
bis.close();
catch (IOException ex)
ex.printStackTrace();
catch (ClassNotFoundException ex)
ex.printStackTrace();
return obj;
public void evict(Object key)
// TODO Auto-generated method stub
System.out.println("del key");
final String keyf = key.toString();
redisTemplate.execute(new RedisCallback<Long>()
public Long doInRedis(RedisConnection connection)
throws DataAccessException
return connection.del(keyf.getBytes());
);
public void clear()
// TODO Auto-generated method stub
System.out.println("clear key");
redisTemplate.execute(new RedisCallback<String>()
public String doInRedis(RedisConnection connection)
throws DataAccessException
connection.flushDb();
return "ok";
);
public <T> T get(Object key, Class<T> type)
// TODO Auto-generated method stub
return null;
public ValueWrapper putIfAbsent(Object key, Object value)
// TODO Auto-generated method stub
return null;
以上是关于redis和spring集成(注解实现,方便,快捷)的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot (24) 使用Spring Cache集成Redis
SpringBoot Validation参数校验 详解自定义注解规则和分组校验