首页 > 代码库 > mybatis+redis实现二级缓存

mybatis+redis实现二级缓存

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

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

上代码:

1、引入spring-data-redis

1 <!-- redis服务 start-->2         <dependency>3           <groupId>org.springframework.data</groupId>4           <artifactId>spring-data-redis</artifactId>5           <version>1.6.2.RELEASE</version>6         </dependency>

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

  1 package com.iafclub.demo.cache;  2   3 import java.io.Serializable;  4 import java.util.Set;  5 import java.util.concurrent.TimeUnit;  6 import java.util.concurrent.locks.ReadWriteLock;  7 import java.util.concurrent.locks.ReentrantReadWriteLock;  8   9 import org.apache.commons.codec.digest.DigestUtils; 10 import org.apache.ibatis.cache.Cache; 11 import org.apache.log4j.Logger; 12 import org.springframework.dao.DataAccessException; 13 import org.springframework.data.redis.connection.RedisConnection; 14 import org.springframework.data.redis.core.RedisCallback; 15 import org.springframework.data.redis.core.RedisTemplate; 16 import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; 17  18 import com.iafclub.demo.util.ApplicationUtil; 19  20 /** 21  * 使用第三方缓存服务器,处理二级缓存 22  * 缓存时间在putObject中设置 23  *  24  * @author chenweixian 25  * 26  */ 27 public class RedisCache implements Cache { 28     private static final Logger logger = Logger.getLogger(RedisCache.class); 29  30     private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); 31  32     private final String COMMON_CACHE_KEY = "demo:MYBATIS:"; 33      34     private String id; 35  36     private JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(); 37     /**所有key*/ 38     private String getKeys() { 39         return COMMON_CACHE_KEY + this.id + ":*"; 40     } 41     /** 42      * 按照一定规则标识key 43      */ 44     private String getKey(Object key) { 45         return COMMON_CACHE_KEY + this.id + ":"+DigestUtils.md5Hex(String.valueOf(key)); 46     } 47      48     public RedisTemplate<String, Serializable> getRedisTemplate(){ 49         return (RedisTemplate<String, Serializable>) ApplicationUtil.getBean("redisTemplate"); 50     } 51      52     public RedisCache(final String id) { 53         if (id == null) { 54             throw new IllegalArgumentException("必须传入ID"); 55         } 56         logger.debug("MybatisRedisCache:id=" + id); 57         this.id = id; 58     } 59  60     @Override 61     public String getId() { 62         return this.id; 63     } 64  65     @Override 66     public void putObject(Object key, Object value) { 67         if (getRedisTemplate()==null){ 68             return ; 69         } 70         if (value != null) { 71             getRedisTemplate().opsForValue().set(getKey(key), 72                     jdkSerializer.serialize(value), 20, TimeUnit.SECONDS); 73         } 74     } 75  76     @Override 77     public Object getObject(Object key) { 78         if (getRedisTemplate()==null){ 79             return null; 80         } 81         try { 82             if (key != null) { 83                 Object obj = getRedisTemplate().opsForValue().get(getKey(key)); 84                 return jdkSerializer.deserialize((byte[]) obj); 85             } 86         } catch (Exception e) { 87             logger.error("redis "); 88         } 89         return null; 90     } 91  92     @Override 93     public Object removeObject(Object key) { 94         if (getRedisTemplate()==null){ 95             return null; 96         } 97         try { 98             if (key != null) { 99                 getRedisTemplate().delete(getKey(key));100                 logger.debug("从缓存中移除-----"+this.id);101             }102         } catch (Exception e) {103         }104         return null;105     }106 107     @Override108     public void clear() {109         if (getRedisTemplate()==null){110             return ;111         }112         try {113             Set<String> keys = getRedisTemplate().keys(getKeys());114             getRedisTemplate().delete(keys);115             logger.debug("出现新增、修改、删除操作,清空对应Mapper缓存======>"+keys.size());116         } catch (Exception e) {117             logger.error(e.getMessage(), e);118         }119     }120 121     @Override122     public int getSize() {123         if (getRedisTemplate()==null){124             return 0;125         }126         Long size = getRedisTemplate().execute(127                 new RedisCallback<Long>() {128                     @Override129                     public Long doInRedis(RedisConnection connection)130                             throws DataAccessException {131                         return connection.dbSize();132                     }133                 });134         return size.intValue();135     }136 137     @Override138     public ReadWriteLock getReadWriteLock() {139         return this.readWriteLock;140     }141 }

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

21 <!-- redis缓存 -->22 <cache type="com.iafclub.demo.cache.RedisCache" eviction="LRU" />
 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 3 <mapper namespace="com.iafclub.demo.dao.DictionaryMapper" > 4     <resultMap id="BaseResultMap" type="com.iafclub.demo.domain.Dictionary" > 5     <id column="auto_id" property="autoId" jdbcType="VARCHAR" /> 6     <result column="type_id" property="typeId" jdbcType="VARCHAR" /> 7     <result column="type_name" property="typeName" jdbcType="VARCHAR" /> 8     <result column="field_key" property="fieldKey" jdbcType="VARCHAR" /> 9     <result column="field_value" property="fieldValue" jdbcType="VARCHAR" />10     <result column="field_back" property="fieldBack" jdbcType="VARCHAR" />11     <result column="field_back2" property="fieldBack2" jdbcType="VARCHAR" />12     <result column="field_back3" property="fieldBack3" jdbcType="VARCHAR" />13     <result column="remark" property="remark" jdbcType="VARCHAR" />14     <result column="editor" property="editor" jdbcType="VARCHAR" />15     <result column="edittime" property="edittime" jdbcType="TIMESTAMP" />16   </resultMap>17   <sql id="Base_Column_List" >18     auto_id, type_id, type_name, field_key, field_value, field_back, field_back2, field_back3, 19     remark, editor, edittime20   </sql>  21 <!-- redis缓存 -->22 <cache type="com.iafclub.demo.cache.RedisCache" eviction="LRU" />23   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >24     select 25     <include refid="Base_Column_List" />26     from t_dictionary27     where auto_id = #{autoId}28   </select>29   <select id="selectAll" resultMap="BaseResultMap" parameterType="java.lang.String" >30     select 31     <include refid="Base_Column_List" />32     from t_dictionary limit 20033   </select>34 </mapper>

4、mybatis配置:

 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 3 <configuration> 4     <settings> 5         <!-- 开启缓存 --> 6         <setting name="cacheEnabled" value="true"/>      7         <!-- Java属性与数据库字段采用驼峰式对应 --> 8         <setting name="mapUnderscoreToCamelCase" value="true" />   9     </settings>10     <!-- 11     <settings>     12         <setting name="useColumnLabel" value="http://www.mamicode.com/true"/>     13         <setting name="useGeneratedKeys" value="http://www.mamicode.com/false"/>     14         <setting name="cacheEnabled" value="http://www.mamicode.com/true" /> 这个配置使全局的映射器启用或禁用缓存15         <setting name="multipleResultSetsEnabled" value="http://www.mamicode.com/true"/>对于未知的SQL查询,允许返回不同的结果集以达到通用的效果16         <setting name="defaultExecutorType" value="http://www.mamicode.com/REUSE" />配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新17         <setting name="lazyLoadingEnabled" value="http://www.mamicode.com/false" />全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载18         <setting name="aggressiveLazyLoading" value="http://www.mamicode.com/true" />19         <setting name="enhancementEnabled" value="http://www.mamicode.com/true"/>20         <setting name="defaultStatementTimeout" value="http://www.mamicode.com/25000" /> 设置超时时间,它决定驱动等待一个数据库响应的时间。21     </settings> 22      -->23 </configuration>

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

 

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

技术分享

 

技术分享

 

mybatis+redis实现二级缓存