1. 介绍
使用mybatis时可以使用二级缓存提高查询速度,进而改善用户体验。
使用redis做mybatis的二级缓存可是内存可控,管理方便。
2. 使用思路
2.1 配置redis.xml 设置redis服务连接各参数
2.1 在配置文件中使用 标签,设置开启二级缓存;
2.2 在mapper.xml 中使用 将cache映射到指定的RedisCacheClass类中;
2.3 映射类RedisCacheClass 实现 MyBatis包中的Cache类,并重写其中各方法;
在重写各方法体中,使用redisFactory和redis服务建立连接,将缓存的数据加载到指定的redis内存中(putObject方法)或将redis服务中的数据从缓存中读取出来(getObject方法);
在redis服务中写入和加载数据时需要借用spring-data-redis.jar中JdkSerializationRedisSerializer.class中的序列化(serialize)和反序列化方法(deserialize),此为包中封装的redis默认的序列化方法;
2.4 映射类中的各方法重写完成后即可实现mybatis数据二级缓存到redis服务中;
3. 代码实践
3.1 配置redis.xml
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd" >
classpath:sysconfig/jdbc.properties
classpath:sysconfig/redis.properties
${jdbc.maxActive}
${jdbc.initialSize}
${jdbc.maxWait}
${jdbc.maxIdle}
${jdbc.minIdle}
18000000
10800000
SELECT 1
true
3.2 mybatis.xml 配置开启二级缓存
/p>
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
3.3 在mapper.xml中映射缓存类RedisCacheClass
/p>
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
select *
from person1=1and user_name=#{user_name}
insert into person(
login_id,
user_name,
gender,
birthday,
remark
)values(
#{login_id},
#{user_name},
#{gender},
#{birthday},
#{remark}
)
3.4 实现Mybatis中的Cache接口
Cache.class源码:
/** Copyright 2009-2012 the original author or authors.
*http://www.apache.org/licenses/LICENSE-2.0*/
packageorg.apache.ibatis.cache;importjava.util.concurrent.locks.ReadWriteLock;public interfaceCache {
String getId();intgetSize();voidputObject(Object key, Object value);
Object getObject(Object key);
Object removeObject(Object key);voidclear();
ReadWriteLock getReadWriteLock();
}
RedisCache.java
packagedemo.redis.cache;importjava.util.concurrent.locks.ReadWriteLock;importjava.util.concurrent.locks.ReentrantReadWriteLock;importorg.apache.ibatis.cache.Cache;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.data.redis.connection.jedis.JedisConnection;importorg.springframework.data.redis.connection.jedis.JedisConnectionFactory;importorg.springframework.data.redis.serializer.JdkSerializationRedisSerializer;importorg.springframework.data.redis.serializer.RedisSerializer;importredis.clients.jedis.exceptions.JedisConnectionException;public class RedisCache implementsCache //实现类
{private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);private staticJedisConnectionFactory jedisConnectionFactory;private finalString id;/*** The {@codeReadWriteLock}.*/
private final ReadWriteLock readWriteLock = newReentrantReadWriteLock();public RedisCache(finalString id) {if (id == null) {throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug("MybatisRedisCache:id=" +id);this.id =id;
}
@Overridepublic voidclear()
{
JedisConnection connection= null;try{
connection=jedisConnectionFactory.getConnection(); //连接清除数据
connection.flushDb();
connection.flushAll();
}catch(JedisConnectionException e)
{
e.printStackTrace();
}finally{if (connection != null) {
connection.close();
}
}
}
@OverridepublicString getId()
{return this.id;
}
@OverridepublicObject getObject(Object key)
{
Object result= null;
JedisConnection connection= null;try{
connection=jedisConnectionFactory.getConnection();
RedisSerializer serializer = newJdkSerializationRedisSerializer(); //借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
result=serializer.deserialize(connection.get(serializer.serialize(key))); //利用其反序列化方法获取值
}catch(JedisConnectionException e)
{
e.printStackTrace();
}finally{if (connection != null) {
connection.close();
}
}returnresult;
}
@OverridepublicReadWriteLock getReadWriteLock()
{return this.readWriteLock;
}
@Overridepublic intgetSize()
{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();
}
}returnresult;
}
@Overridepublic voidputObject(Object key, Object value)
{
JedisConnection connection= null;try{
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject:"+key+"="+value);
connection=jedisConnectionFactory.getConnection();
RedisSerializer serializer = newJdkSerializationRedisSerializer(); //借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
connection.set(serializer.serialize(key), serializer.serialize(value)); //利用其序列化方法将数据写入redis服务的缓存中
}catch(JedisConnectionException e)
{
e.printStackTrace();
}finally{if (connection != null) {
connection.close();
}
}
}
@OverridepublicObject removeObject(Object key)
{
JedisConnection connection= nullObject result= null;try{
connection=jedisConnectionFactory.getConnection();
RedisSerializer serializer = newJdkSerializationRedisSerializer();
result=connection.expire(serializer.serialize(key), 0);
}catch(JedisConnectionException e)
{
e.printStackTrace();
}finally{if (connection != null) {
connection.close();
}
}returnresult;
}public static voidsetJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
RedisCache.jedisConnectionFactory=jedisConnectionFactory;
}
}
4. 总结
通过重写Cache类中的方法,将mybatis中默认的缓存空间映射到redis空间中。