您的位置:首页 > 数据库 > Redis

mybatis+redis实现二级缓存

2016-11-28 18:29 567 查看
在网上看了很多资料,发现例子都是千篇一律的相互复制。而且,使用的都是jedis的客户端。。我这里使用的是redistemplate类实现。

缓存的原理。。实现cache类接口,当哪个类需要缓存的时候,就直接将cache标签引入,并且制定我们的缓存类就可以了。

上代码:

1、引入spring-data-redis

<!-- redis服务 start-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>


2、java缓存类,至于里面如何获取bean,ApplicationUtil.getBean("redisTemplate"),请查看我上篇文章:普通java类获取springbean的方法

package com.iafclub.demo.cache;

import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.ibatis.cache.Cache;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;

import com.iafclub.demo.util.ApplicationUtil;

/**
* 使用第三方缓存服务器,处理二级缓存
* 缓存时间在putObject中设置
*
* @author chenweixian
*
*/
public class RedisCache implements Cache {
private static final Logger logger = Logger.getLogger(RedisCache.class);

private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

private final String COMMON_CACHE_KEY = "demo:MYBATIS:";

private String id;

private JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
/**所有key*/
private String getKeys() {
return COMMON_CACHE_KEY + this.id + ":*";
}
/**
* 按照一定规则标识key
*/
private String getKey(Object key) {
return COMMON_CACHE_KEY + this.id + ":"+DigestUtils.md5Hex(String.valueOf(key));
}

public RedisTemplate<String, Serializable> getRedisTemplate(){
return (RedisTemplate<String, Serializable>) ApplicationUtil.getBean("redisTemplate");
}

public RedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("必须传入ID");
}
logger.debug("MybatisRedisCache:id=" + id);
this.id = id;
}

@Override
public String getId() {
return this.id;
}

@Override
public void putObject(Object key, Object value) {
if (getRedisTemplate()==null){
return ;
}
if (value != null) {
getRedisTemplate().opsForValue().set(getKey(key),
jdkSerializer.serialize(value), 20, TimeUnit.SECONDS);
}
}

@Override
public Object getObject(Object key) {
if (getRedisTemplate()==null){
return null;
}
try {
if (key != null) {
Object obj = getRedisTemplate().opsForValue().get(getKey(key));
return jdkSerializer.deserialize((byte[]) obj);
}
} catch (Exception e) {
logger.error("redis ");
}
return null;
}

@Override
public Object removeObject(Object key) {
if (getRedisTemplate()==null){
return null;
}
try {
if (key != null) {
getRedisTemplate().delete(getKey(key));
logger.debug("从缓存中移除-----"+this.id);
}
} catch (Exception e) {
}
return null;
}

@Override
public void clear() {
if (getRedisTemplate()==null){
return ;
}
try {
Set<String> keys = getRedisTemplate().keys(getKeys());
getRedisTemplate().delete(keys);
logger.debug("出现新增、修改、删除操作,清空对应Mapper缓存======>"+keys.size());
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}

@Override
public int getSize() {
if (getRedisTemplate()==null){
return 0;
}
Long size = getRedisTemplate().execute(
new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.dbSize();
}
});
return size.intValue();
}

@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
}


3、mybatis配置:注意加粗标红,斜线部分:

21 <!-- redis缓存 -->
22 <cache type="com.iafclub.demo.cache.RedisCache" eviction="LRU" />


 <?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.iafclub.demo.dao.DictionaryMapper" >
<resultMap id="BaseResultMap" type="com.iafclub.demo.domain.Dictionary" >
<id column="auto_id" property="autoId" jdbcType="VARCHAR" />
<result column="type_id" property="typeId" jdbcType="VARCHAR" />
<result column="type_name" property="typeName" jdbcType="VARCHAR" />
<result column="field_key" property="fieldKey" jdbcType="VARCHAR" />
<result column="field_value" property="fieldValue" jdbcType="VARCHAR" />
<result column="field_back" property="fieldBack" jdbcType="VARCHAR" />
<result column="field_back2" property="fieldBack2" jdbcType="VARCHAR" />
<result column="field_back3" property="fieldBack3" jdbcType="VARCHAR" />
<result column="remark" property="remark" jdbcType="VARCHAR" />
<result column="editor" property="editor" jdbcType="VARCHAR" />
<result column="edittime" property="edittime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Base_Column_List" >
auto_id, type_id, type_name, field_key, field_value, field_back, field_back2, field_back3,
remark, editor, edittime
</sql>
21 <!-- redis缓存 --> 22 <cache type="com.iafclub.demo.cache.RedisCache" eviction="LRU" />
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from t_dictionary
where auto_id = #{autoId}
</select>
<select id="selectAll" resultMap="BaseResultMap" parameterType="java.lang.String" >
select
<include refid="Base_Column_List" />
from t_dictionary limit 200
</select>
</mapper>


4、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"/>
<!-- Java属性与数据库字段采用驼峰式对应 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<!--
<settings>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="cacheEnabled" value="true" /> 这个配置使全局的映射器启用或禁用缓存
<setting name="multipleResultSetsEnabled" value="true"/>对于未知的SQL查询,允许返回不同的结果集以达到通用的效果
<setting name="defaultExecutorType" value="REUSE" />配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新
<setting name="lazyLoadingEnabled" value="false" />全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载
<setting name="aggressiveLazyLoading" value="true" />
<setting name="enhancementEnabled" value="true"/>
<setting name="defaultStatementTimeout" value="25000" /> 设置超时时间,它决定驱动等待一个数据库响应的时间。
</settings>
-->
</configuration>


5、其他页面实现,次要。。。

n、测试运行结果:只有第一次查询,发送了sql,第二次后,就不会发送sql,直接在redis中查询。如果进行增删改,都会清空,然后,再发sql



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: