转载:http://blog.csdn.net/xiadi934/article/details/50786293

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

1、整体思路

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

2、pom.xml中加入Maven依赖

 1 <!-- spring-redis实现 -->
2 <dependency>
3 <groupId>org.springframework.data</groupId>
4 <artifactId>spring-data-redis</artifactId>
5 <version>1.6.2.RELEASE</version>
6 </dependency>
7 <!-- redis客户端jar -->
8 <dependency>
9 <groupId>redis.clients</groupId>
10 <artifactId>jedis</artifactId>
11 <version>2.8.0</version>
12 </dependency>
13 <!-- Ehcache实现,用于参考 -->
14 <dependency>
15 <groupId>org.mybatis</groupId>
16 <artifactId>mybatis-ehcache</artifactId>
17 <version>1.0.0</version>
18 </dependency>

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

 1 <!-- 引入数据库配置文件 -->
2 <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
3 <property name="locations">
4 <list>
5 <value>classpath:jdbc.properties</value>
6 <value>classpath:redis.properties</value>
7 </list>
8 </property>
9 </bean>
10 <!-- redis数据源 -->
11 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
12 <property name="maxIdle" value="${redis.maxIdle}" />
13 <property name="maxTotal" value="${redis.maxActive}" />
14 <property name="maxWaitMillis" value="${redis.maxWait}" />
15 <property name="testOnBorrow" value="${redis.testOnBorrow}" />
16 </bean>
17 <!-- Spring-redis连接池管理工厂 -->
18 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
19 p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>
20 <!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
21 <bean id="redisCacheTransfer" class="com.strive.cms.cache.RedisCacheTransfer">
22 <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
23 </bean>

4、创建缓存实现类RedisCache

  1 /**
2 *
3 * @描述: 使用第三方内存数据库Redis作为二级缓存
4 * @版权: Copyright (c) 2016
5 * @作者: xiad
6 * @版本: 1.0
7 * @创建日期: 2016年3月2日
8 * @创建时间: 下午8:02:57
9 */
10 public class RedisCache implements Cache
11 {
12 private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
13
14 private static JedisConnectionFactory jedisConnectionFactory;
15
16 private final String id;
17
18 /**
19 * The {@code ReadWriteLock}.
20 */
21 private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
22
23 public RedisCache(final String id) {
24 if (id == null) {
25 throw new IllegalArgumentException("Cache instances require an ID");
26 }
27 logger.debug("MybatisRedisCache:id=" + id);
28 this.id = id;
29 }
30
31 @Override
32 public void clear()
33 {
34 JedisConnection connection = null;
35 try
36 {
37 connection = jedisConnectionFactory.getConnection();
38 connection.flushDb();
39 connection.flushAll();
40 }
41 catch (JedisConnectionException e)
42 {
43 e.printStackTrace();
44 }
45 finally
46 {
47 if (connection != null) {
48 connection.close();
49 }
50 }
51 }
52
53 @Override
54 public String getId()
55 {
56 return this.id;
57 }
58
59 @Override
60 public Object getObject(Object key)
61 {
62 Object result = null;
63 JedisConnection connection = null;
64 try
65 {
66 connection = jedisConnectionFactory.getConnection();
67 RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
68 result = serializer.deserialize(connection.get(serializer.serialize(key)));
69 }
70 catch (JedisConnectionException e)
71 {
72 e.printStackTrace();
73 }
74 finally
75 {
76 if (connection != null) {
77 connection.close();
78 }
79 }
80 return result;
81 }
82
83 @Override
84 public ReadWriteLock getReadWriteLock()
85 {
86 return this.readWriteLock;
87 }
88
89 @Override
90 public int getSize()
91 {
92 int result = 0;
93 JedisConnection connection = null;
94 try
95 {
96 connection = jedisConnectionFactory.getConnection();
97 result = Integer.valueOf(connection.dbSize().toString());
98 }
99 catch (JedisConnectionException e)
100 {
101 e.printStackTrace();
102 }
103 finally
104 {
105 if (connection != null) {
106 connection.close();
107 }
108 }
109 return result;
110 }
111
112 @Override
113 public void putObject(Object key, Object value)
114 {
115 JedisConnection connection = null;
116 try
117 {
118 connection = jedisConnectionFactory.getConnection();
119 RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
120 connection.set(serializer.serialize(key), serializer.serialize(value));
121 }
122 catch (JedisConnectionException e)
123 {
124 e.printStackTrace();
125 }
126 finally
127 {
128 if (connection != null) {
129 connection.close();
130 }
131 }
132 }
133
134 @Override
135 public Object removeObject(Object key)
136 {
137 JedisConnection connection = null;
138 Object result = null;
139 try
140 {
141 connection = jedisConnectionFactory.getConnection();
142 RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
143 result =connection.expire(serializer.serialize(key), 0);
144 }
145 catch (JedisConnectionException e)
146 {
147 e.printStackTrace();
148 }
149 finally
150 {
151 if (connection != null) {
152 connection.close();
153 }
154 }
155 return result;
156 }
157
158 public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
159 RedisCache.jedisConnectionFactory = jedisConnectionFactory;
160 }
161
162 }

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

 1 /**
2 *
3 * @描述: 静态注入中间类
4 * @版权: Copyright (c) 2016
5 * @作者: xiad
6 * @版本: 1.0
7 * @创建日期: 2016年3月2日
8 * @创建时间: 下午8:02:57
9 */
10 public class RedisCacheTransfer
11 {
12
13 @Autowired
14 public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
15 RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
16 }
17
18 }

6、配置文件redis.properties

1 # Redis settings
2 redis.host=192.168.25.132
3 redis.port=6379
4 redis.pass=
5
6 redis.maxIdle=300
7 redis.maxActive=600
8 redis.maxWait=1000
9 redis.testOnBorrow=true

7、mapper中加入MyBatis二级缓存

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

8、Mybatis全局配置

 1 <?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6 <!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->
7 <settings>
8
9 <!-- 全局映射器启用缓存 -->
10 <setting name="cacheEnabled" value="true"/>
11
12 <!-- 查询时,关闭关联对象即时加载以提高性能 -->
13 <setting name="lazyLoadingEnabled" value="false"/>
14
15 <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
16 <setting name="multipleResultSetsEnabled" value="true"/>
17
18 <!-- 允许使用列标签代替列名 -->
19 <setting name="useColumnLabel" value="true"/>
20
21 <!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
22 <setting name="useGeneratedKeys" value="false"/>
23
24 <!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL -->
25 <setting name="autoMappingBehavior" value="PARTIAL"/>
26
27 <!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE -->
28 <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
29
30 <!-- 数据库超过25000秒仍未响应则超时 -->
31 <!-- <setting name="defaultStatementTimeout" value="25000" /> -->
32
33 <!-- Allows using RowBounds on nested statements -->
34 <setting name="safeRowBoundsEnabled" value="false"/>
35
36 <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->
37 <setting name="mapUnderscoreToCamelCase" value="true"/>
38
39 <!-- 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
40 local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->
41 <setting name="localCacheScope" value="SESSION"/>
42
43 <!-- 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
44 like NULL, VARCHAR or OTHER. -->
45 <setting name="jdbcTypeForNull" value="OTHER"/>
46
47 <!-- Specifies which Object's methods trigger a lazy load -->
48 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
49
50 <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
51 <setting name="aggressiveLazyLoading" value="true"/>
52
53 </settings>
54
55 </configuration>

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

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

10、测试代码

 1 @RunWith(SpringJUnit4ClassRunner.class)
2 @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
3 public class MyBatisCacheSecondTest
4 {
5 private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);
6
7 @Autowired
8 private SiteService service;
9
10 /*
11 * 二级缓存测试
12 */
13 @Test
14 public void testCache2() {
15 PageInfo<Site> page1 = service.querySite("", 1, 2, "", "");
16 logger.info(page1.getList().get(1).getName());
17
18 PageInfo<Site> page2 = service.querySite("", 2, 2, "", "");
19 logger.info(page2.getList().get(0).getName());
20
21 PageInfo<Site> page3 = service.querySite("", 1, 2, "", "");
22 logger.info(page3.getList().get(0).getName());
23 }
24
25 }

首次运行结果 
 
后续运行结果 
 
同条件的查询语句可以发现,已经不再查询Mysql,而是直接取Redis数据 
查看Redis数据库 keys *, 会发现多了很多数据,结果如下 
 
至此,Redis基本配置成功。

SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置的更多相关文章

  1. SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置

    2016年03月03日 10:37:47 标签: mysql / redis / mybatis / spring mvc / spring 33805 项目环境: 在SpringMVC + MyBa ...

  2. mybatis 使用redis实现二级缓存(spring boot)

    mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...

  3. SpringMVC+Spring+Mybatis+Mysql项目搭建

    眼下俺在搭建一个自己的个人站点玩玩.一边练习.一边把用到的技术总结一下,日后好复习. 站点框架大致例如以下图所看到的: 眼下仅仅用到了SpringMVC+Spring+Mybatis+Mysql.把它 ...

  4. Mybatis整合Redis实现二级缓存

    Mybatis集成ehcache . 为什么需要缓存 拉高程序的性能 . 什么样的数据需要缓存 很少被修改或根本不改的数据 业务场景比如:耗时较高的统计分析sql.电话账单查询sql等 . ehcac ...

  5. springmvc学习总结(二) -- maven+springmvc+spring+mybatis+mysql详细搭建整合过程讲解

    @_@ 写在最前 之前分享过下面这几篇: mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上)(附demo和搭建过程遇到的问题解决方法) myba ...

  6. maven+springmvc+spring+mybatis+mysql详细搭建整合过程讲解

    转自:https://www.cnblogs.com/lmei/p/7190755.html?utm_source=itdadao&utm_medium=referral @_@ 写在最前 之 ...

  7. springboot+mybatis 用redis作二级缓存

    1.加入相关依赖包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  8. mybatis结合redis实战二级缓存(六)

    之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSC ...

  9. SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

随机推荐

  1. python核心编程正则表达式练习题1-2匹配由单个空格分隔的任意单词对,也就是性和名

    # 匹配由单个空格分隔的任意单词对,也就是姓和名 import re patt = '[A-Za-z]+ [A-Za-z]+' # 方法一 +加号操作符匹配它左边的正则表达式至少出现一次的情况 # p ...

  2. linux高性能服务器编程pdf免费下载

    百度云盘:链接: https://pan.baidu.com/s/1pLp4hHx 密码: wn4k

  3. 磁盘空间命令df/du/free

    1.df 显示文件系统大小 -h 以易读方式显示 -k KB -m MB -a 显示所有 2. du 显示文件大小 -h 只显示目录 -a 所有 -s 只显示总量 3.free 显示内存 -k -m ...

  4. python基础练习题08

    写一个登录程序,让用户输入账号和密码,输入用户和密码输入正确的话,提示你 xxx,欢迎登录,今天的日期是xxx,程序结束.错误的话,提示账号/密码输入错误, 最多输入3次,如果输入3次都没有登录成功, ...

  5. Flask【第10篇】:自定义Form组件

    自定义Form组件 一.wtforms源码流程 1.实例化流程分析 1 # 源码流程 2 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: ...

  6. java<T>泛型

    泛型 1.泛型的概述 在JDK1.5之前,把对象放入到集合中,集合不会记住元素的类型,取出时,全都变成Object类型.泛型是jdk5引入的类型机制,就是将类型参数化,它是早在1999年就制定的jsr ...

  7. 1222/2516. Kup

    题目描述 Description 首先你们得承认今天的题目很短很简洁... 然后,你们还得承认接下来这个题目的描述更加简洁!!! Task:给出一个N*N(1≤N≤2000)的矩阵,还给出一个整数K. ...

  8. 实验 5 Spark SQL 编程初级实践

    实验 5  Spark SQL 编程初级实践    参考厦门大学林子雨 1. Spark SQL 基本操作 将下列 json 数据复制到你的 ubuntu 系统/usr/local/spark 下,并 ...

  9. @JsonView注解指定返回的model类中显示的字段

    1.User类 package com.imooc.model; import com.fasterxml.jackson.annotation.JsonView; /** * @author oy ...

  10. Luogu P4550 收集邮票

    题目链接:Click here Solution: 本题直接推价格似乎很难,考虑先从购买次数入手 设购买次数\(g(i)\)为当前有\(i\)种不同的邮票,要买到\(n\)种的期望购买次数 可以由期望 ...