mybatis提供了cache接口让开发者可以很好的去扩展实现自己的缓存使用。这个可以参考mybatis官方的ehcache实现。本文主要介绍自己使用mybatis集成redis的实践,在实践过程中采用了3种方式,下面是几种方式使用介绍。
一,使用原生jedis
这种方式只需要加入jedis
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency>
网上有许多的例子,例如http://www.tuicool.com/articles/quqmy2
二,使用mybatis-redis
mybatis-redis是mybatis集成redis实现二级缓存的一个实现,和mybatis-memcached类似,这种方式是mybatis集成redis最快的方式,无需自己编写代码实现cache接口
mybatis-redis的官方git地址https://github.com/mybatis/redis-cache
项目集成mybatis-redis
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
在mybatis配置中开启缓存
<setting name="cacheEnabled" value="true"/>
<?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="aggressiveLazyLoading" value="true"/>-->
</settings>
<plugins>
<!--mybatis 分页插件-->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql" />
</plugin>
</plugins>
</configuration>
在项目的资源(maven resource)目录中加入redis.propertis文件
host=localhost
port=6379
timeout=5000
最后在mapper映射文件中开启cache即可
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lisi.test.dao.UserDao">
<!--启用mybatis-redis-->
<cache type="org.mybatis.caches.redis.RedisCache"/>
<resultMap type="User" id="UserResult">
<result property="id" column="id"/>
<result property="uuid" column="uuid"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="createTime" column="create_time"/>
</resultMap>
<insert id="save" parameterType="User">
<selectKey resultType="int" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
insert into
t_user(uuid,username,password,create_time)
values(#{uuid},#{username},#{password},#{createTime})
</insert>
<delete id="delete" parameterType="long">
delete from t_user where id =
#{id}
</delete>
<select id="getById" parameterType="long" resultType="User">
select
id,uuid,username,password,create_time as createTime from t_user
where id=#{id}
</select>
<update id="update" parameterType="User">
update t_user set
username=#{username}
where id = #{id}
</update>
</mapper>
三,使用spring-data-redis
spring-data-redis是比较有名的项目,相关资料很多。
使用spring-data-redis的关键依赖,因为用到spring,所以spring的相关依赖是需要加入的
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
mybatis使用spring-data-redis集成redis缓存和第一种方式很相似,都需要自己实现cache接口,只是使用spring-data-redis后方便使用spring的方式来管理,
代码:
/**
* Use JedisConnectionFactory
*/
public class SpringRedisCache implements Cache {
private static Logger logger = LoggerFactory.getLogger(SpringRedisCache.class);
private JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory)SpringContextHolder.getBean("jedisConnectionFactory");
private final String id;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public SpringRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug("SpringRedisCache:id=" + id);
this.id = id;
}
@Override
public void clear() {
RedisConnection 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;
RedisConnection 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;
RedisConnection 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) {
RedisConnection 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) {
RedisConnection 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;
}
}
上面使用的SpringContextHolder源码
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
SpringContextHolder.context = context;
}
public static <T> T getBean(String name){
return (T)context.getBean(name);
}
}
在项目的资源(maven resource)目录中加入redis.propertis文件
redis.host=localhost
redis.port=6379
redis.pass=
redis.timeout=5000
redis.default.db=0
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
在spring中配置加入
<!-- redis数据池配置 -->
<bean id="jedisPoolConfig" 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-data-redis connectFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true"></property>
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.pass}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.db}"/>
<constructor-arg index="0" ref="jedisPoolConfig" />
</bean>
最后修改mapper文件中cache的type为SpringRedisCache即可
使用spring-data-redis还可以使用它的RedisTemplate去实现cache接口,不过因为RedisTemplate是对JedisConnectionFactory的包装,在spring配置文件的配置更多