项目环境: 在SpringMVC + MyBatis + MySQL。Redis部署在Linux虚拟机。
1、整体思路
参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅)使用Spring管理Redis连接池模仿EhcacheCache,实现RedisCache
2、pom.xml中加入Maven依赖
<dependency>
<groupId>org.springframework.data
</groupId>
<artifactId>spring-data-redis
</artifactId>
<version>1.6.2.RELEASE
</version>
</dependency>
<dependency>
<groupId>redis.clients
</groupId>
<artifactId>jedis
</artifactId>
<version>2.8.0
</version>
</dependency>
<dependency>
<groupId>org.mybatis
</groupId>
<artifactId>mybatis-ehcache
</artifactId>
<version>1.0.0
</version>
</dependency>
123456789101112131415161718
123456789101112131415161718
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>
<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>
<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="redisCacheTransfer" class="com.strive.cms.cache.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
</bean>
1234567891011121314151617181920212223
1234567891011121314151617181920212223
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;
}
@Override
public void clear()
{
JedisConnection connection =
null;
try
{
connection = jedisConnectionFactory.getConnection();
connection.flushDb();
connection.flushAll();
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection !=
null) {
connection.close();
}
}
}
@Override
public String
getId()
{
return this.id;
}
@Override
public 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;
}
@Override
public ReadWriteLock
getReadWriteLock()
{
return this.readWriteLock;
}
@Override
public 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;
}
@Override
public 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();
}
}
}
@Override
public 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;
}
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
5、创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入
/**
*
* @描述: 静态注入中间类
* @版权: Copyright (c) 2016
* @作者: xiad
* @版本: 1.0
* @创建日期: 2016年3月2日
* @创建时间: 下午8:02:57
*/
public class RedisCacheTransfer
{
@Autowired
public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}
123456789101112131415161718
123456789101112131415161718
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
123456789
123456789
7、mapper中加入MyBatis二级缓存
<mapper namespace="com.strive.cms.dao.site.CatalogMapper" >
<cache type="com.strive.cms.cache.RedisCache"/>
.....
</mapper>
1234
1234
8、Mybatis全局配置
<?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>
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="false"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
</configuration>
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
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
1234567891011121314151617181920212223
1234567891011121314151617181920212223
10、测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:applicationContext.xml"})
public class MyBatisCacheSecondTest
{
private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);
@Autowired
private SiteService service;
@Test
public 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());
}
}
12345678910111213141516171819202122232425
12345678910111213141516171819202122232425
首次运行结果 后续运行结果 同条件的查询语句可以发现,已经不再查询mysql,而是直接取redis数据 查看Redis数据库 keys *, 会发现多了很多数据,结果如下 至此,Redis基本配置成功。
如有疑问或建议,欢迎留言与指点