项目环境: 在SpringMVC + MyBatis + Mysql。Redis部署在Linux虚拟机。

1、整体思路

  • 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅)
  • 使用Spring管理Redis连接池
  • 模仿EhcacheCache,实现RedisCache

2、pom.xml中加入Maven

<!-- spring-redis实现 -->
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.6.2.RELEASE</version>
</dependency>
<!-- redis客户端jar -->
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.0</version>
</dependency>
<!-- Ehcache实现,用于参考 -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.0</version>
</dependency>

3、引入applicationContext.xml中引入redis配置

<!-- 引入数据库配置文件 -->
<bean id="propertyConfigurer"    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:jdbc.properties</value><value>classpath:redis.properties</value></list></property>
</bean>
<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  <property name="maxIdle" value="${redis.maxIdle}" />  <property name="maxTotal" value="${redis.maxActive}" />  <property name="maxWaitMillis" value="${redis.maxWait}" />  <property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- Spring-redis连接池管理工厂 -->
<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"/>
<!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
<bean id="redisCacheTransfer" class="com.strive.cms.cache.RedisCacheTransfer"><property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
</bean>

4、创建缓存实现类RedisCache

/*** * @描述: 使用第三方内存数据库Redis作为二级缓存* @版权: Copyright (c) 2016 * @作者: xiad* @版本: 1.0 * @创建日期: 2016年3月2日 * @创建时间: 下午8:02:57*/
public class RedisCache implements Cache
{private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);private static JedisConnectionFactory jedisConnectionFactory;private final String id;/*** The {@code ReadWriteLock}.*/private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();public RedisCache(final String id) {if (id == null) {throw new IllegalArgumentException("Cache instances require an ID");}logger.debug("MybatisRedisCache:id=" + id);this.id = id;}@Overridepublic void clear(){JedisConnection connection = null;try{connection = jedisConnectionFactory.getConnection();connection.flushDb();connection.flushAll();}catch (JedisConnectionException e){e.printStackTrace();}finally{if (connection != null) {connection.close();}}}@Overridepublic String getId(){return this.id;}@Overridepublic Object getObject(Object key){Object result = null;JedisConnection connection = null;try{connection = jedisConnectionFactory.getConnection();RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();result = serializer.deserialize(connection.get(serializer.serialize(key)));}catch (JedisConnectionException e){e.printStackTrace();}finally{if (connection != null) {connection.close();}}return result;}@Overridepublic ReadWriteLock getReadWriteLock(){return this.readWriteLock;}@Overridepublic int getSize(){int result = 0;JedisConnection connection = null;try{connection = jedisConnectionFactory.getConnection();result = Integer.valueOf(connection.dbSize().toString());}catch (JedisConnectionException e){e.printStackTrace();}finally{if (connection != null) {connection.close();}}return result;}@Overridepublic void putObject(Object key, Object value){JedisConnection connection = null;try{connection = jedisConnectionFactory.getConnection();RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();connection.set(serializer.serialize(key), serializer.serialize(value));}catch (JedisConnectionException e){e.printStackTrace();}finally{if (connection != null) {connection.close();}}}@Overridepublic Object removeObject(Object key){JedisConnection connection = null;Object result = null;try{connection = jedisConnectionFactory.getConnection();RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();result =connection.expire(serializer.serialize(key), 0);}catch (JedisConnectionException e){e.printStackTrace();}finally{if (connection != null) {connection.close();}}return result;}public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {RedisCache.jedisConnectionFactory = jedisConnectionFactory;}}

5、创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入

/*** * @描述: 静态注入中间类* @版权: Copyright (c) 2016 * @作者: xiad* @版本: 1.0 * @创建日期: 2016年3月2日 * @创建时间: 下午8:02:57*/
public class RedisCacheTransfer
{@Autowiredpublic void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {RedisCache.setJedisConnectionFactory(jedisConnectionFactory);}}

6、配置文件redis.properties

# Redis settings
redis.host=192.168.25.132
redis.port=6379
redis.pass=redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true  

7、mapper中加入MyBatis二级缓存

<mapper namespace="com.strive.cms.dao.site.CatalogMapper" ><cache type="com.strive.cms.cache.RedisCache"/>.....
</mapper>

8、Mybatis全局配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 配置mybatis的缓存,延迟加载等等一系列属性 --><settings><!-- 全局映射器启用缓存 --><setting name="cacheEnabled" value="true"/><!-- 查询时,关闭关联对象即时加载以提高性能 --><setting name="lazyLoadingEnabled" value="false"/><!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 --><setting name="multipleResultSetsEnabled" value="true"/><!-- 允许使用列标签代替列名 --><setting name="useColumnLabel" value="true"/><!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 --><setting name="useGeneratedKeys" value="false"/><!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL --><setting name="autoMappingBehavior" value="PARTIAL"/><!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE --><!-- <setting name="defaultExecutorType" value="BATCH" /> --><!-- 数据库超过25000秒仍未响应则超时 --><!-- <setting name="defaultStatementTimeout" value="25000" /> --><!-- Allows using RowBounds on nested statements --><setting name="safeRowBoundsEnabled" value="false"/><!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. --><setting name="localCacheScope" value="SESSION"/><!-- Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values like NULL, VARCHAR or OTHER. --><setting name="jdbcTypeForNull" value="OTHER"/><!-- Specifies which Object's methods trigger a lazy load --><setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/><!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 --><setting name="aggressiveLazyLoading" value="true"/></settings></configuration>

9、打印Sql日志,方便测试

#定义LOG输出级别为INFO
log4j.rootLogger=INFO,Console,File####定义日志输出目的地为控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
#可以灵活地指定日志输出格式,下面一行是指定具体的格式
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n####文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.File = org.apache.log4j.RollingFileAppender
#指定输出目录
log4j.appender.File.File = logs/ssm.log
#定义文件最大大小
log4j.appender.File.MaxFileSize = 10MB
#输出所以日志,如果换成DEBUG表示输出DEBUG以上级别日志
log4j.appender.File.Threshold = ALL
log4j.appender.File.layout = org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n####显示本项目SQL语句部分
log4j.logger.com.strive.cms=DEBUG

10、测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MyBatisCacheSecondTest
{private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);    @Autowiredprivate  SiteService service;/** 二级缓存测试*/@Testpublic void testCache2() {PageInfo<Site> page1 = service.querySite("", 1, 2, "", "");logger.info(page1.getList().get(1).getName());PageInfo<Site> page2 = service.querySite("", 2, 2, "", "");logger.info(page2.getList().get(0).getName());PageInfo<Site> page3 = service.querySite("", 1, 2, "", "");logger.info(page3.getList().get(0).getName());}   }

首次运行结果


后续运行结果 

同条件的查询语句可以发现,已经不再查询Mysql,而是直接取Redis数据 
查看Redis数据库 keys *, 会发现多了很多数据,结果如下 

至此,Redis基本配置成功。

Redis 整合spring ,做mysql的缓存相关推荐

  1. Redis集群——利用Gearman在Lnmp架构中做MySQL的缓存服务器

    一.概述 Redis的集群主要是使用切片技术来搭建的,简单来说就是把所有KEY分散存放到不同的redis节点上(不要把鸡蛋都放在一个篮子里). 1. 集群基本原理 Redis集群中内置了16384个槽 ...

  2. 如何使用Redis做MySQL的缓存

    应用Redis实现数据的读写,同时利用队列处理器定时将数据写入mysql. 同时要注意避免冲突,在redis启动时去mysql读取所有表键值存入redis中,往redis写数据时,对redis主键自增 ...

  3. Redis整合Spring结合使用缓存实例(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文介绍了如何在Spring中配置redis,并通过Spring中AOP的思想,将缓存的 ...

  4. Redis整合Spring结合使用缓存实例

    2019独角兽企业重金招聘Python工程师标准>>> 摘要:本文介绍了如何在Spring中配置redis,并通过Spring中AOP的思想,将缓存的方法切入到有需要进入缓存的类或方 ...

  5. redis配置mysql缓存_Redis做mysql的缓存服务器

    一redis简介:redis 是一个高性能的 key-value 数据库. redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好 ...

  6. Redis学习总结(3)——Redis整合Spring结合使用缓存实例

    摘要:本文介绍了如何在Spring中配置redis,并通过Spring中AOP的思想,将缓存的方法切入到有需要进入缓存的类或方法前面. 一.Redis介绍 什么是Redis? redis是一个key- ...

  7. Spring Boot——Spring Session Redis整合Spring Security时错误【RedisConnectionFactory is required】解决方案

    问题描述 异常栈栈底 Caused by: java.lang.IllegalStateException: RedisConnectionFactory is requiredat org.spri ...

  8. Redis整合Spring Data Redis 开发key和value乱码

    Spring整合Redis默认使用的是JDK的序列化 将key,value的序列化改成Spring的就行了. 这种在 可视化界面  看见□□ 其实只是可视化界面显示问题, 真正的数据, 其实并无乱码. ...

  9. java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)...

    一.缓存 当系统的并发量上来了,如果我们频繁地去访问数据库,那么会使数据库的压力不断增大,在高峰时甚至可以出现数据库崩溃的现象.所以一般我们会使用缓存来解决这个数据库并发访问问题,用户访问进来,会先从 ...

最新文章

  1. ROS系统 C++或Python实现订阅者Subscriber
  2. C语言面试基础知识整理
  3. threejs加载模型挤压变形_车用水阀套零件冷挤压成形数值模拟试验研究
  4. 机器学习——支持向量机SVM之非线性模型(原问题转化为对偶问题)
  5. oracle 存储过程 stored procedure 查询一条记录或多条记录
  6. php mysql保存unicode_使用PHP和MySQL存储和显示unicode字符串(हिन्दी)
  7. P3348-[ZJOI2016]大森林【LCT】
  8. MPLS virtual private network 地址重叠实验(华为设备)
  9. C# ComBox 垂直滚动条
  10. 广播域与冲突域的区别
  11. 年度双十佳广告爆笑金庸版
  12. html中url格式,web地址的URL一般格式为
  13. jquery读取xml比较js读取xml 比比就知道
  14. Windows列出系统所有补丁(wmic)
  15. Paranoid String
  16. z-index什么意思
  17. 用电位器通过STC12C2052AD单片机片内AD和PWM控制电机无极变速
  18. 【转】eclipse, Log4j配置(真心的详细~)
  19. 【USB接口程序设计】
  20. Metasploit用法大全

热门文章

  1. SQL Server 查询分解
  2. iOS端URL编码和解码过程
  3. 一图掌握PEST分析模型及案例
  4. ATH9K Driver Learning Part III: Data packet transmission
  5. linux 安装ath9k_htc驱动
  6. 在 iOS 6开始 UICollectionView 1
  7. 怎样防止文件在停电时丢失
  8. 九针串口跟电脑主板接法
  9. php 说说,PHP利用Qzone的说说接口发表说说开发日记
  10. Java标准简历制作