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     @Override
108     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     @Override
122     public int getSize() {
123         if (getRedisTemplate()==null){
124             return 0;
125         }
126         Long size = getRedisTemplate().execute(
127                 new RedisCallback<Long>() {
128                     @Override
129                     public Long doInRedis(RedisConnection connection)
130                             throws DataAccessException {
131                         return connection.dbSize();
132                     }
133                 });
134         return size.intValue();
135     }
136
137     @Override
138     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, edittime
20   </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_dictionary
27     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 200
33   </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="true"/>
13         <setting name="useGeneratedKeys" value="false"/>
14         <setting name="cacheEnabled" value="true" /> 这个配置使全局的映射器启用或禁用缓存
15         <setting name="multipleResultSetsEnabled" value="true"/>对于未知的SQL查询,允许返回不同的结果集以达到通用的效果
16         <setting name="defaultExecutorType" value="REUSE" />配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新
17         <setting name="lazyLoadingEnabled" value="false" />全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载
18         <setting name="aggressiveLazyLoading" value="true" />
19         <setting name="enhancementEnabled" value="true"/>
20         <setting name="defaultStatementTimeout" value="25000" /> 设置超时时间,它决定驱动等待一个数据库响应的时间。
21     </settings>
22      -->
23 </configuration>

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

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

时间: 2024-12-10 22:12:49

mybatis+redis实现二级缓存的相关文章

SpringBoot+Mybatis+redis实现二级缓存

对于查询比较多的项目可以考虑配置二级缓存,mybatis本身的二级缓存是缓存到本地,但是对于多个节点的项目来说,可能会出现数据不一致的问题,所以采用redis缓存,这样二级缓存的数据就可以缓存到内存,可实现多个节点项目的数据同步. 1.配置redis的连接 #redis gmall.redis.host=172.16.1.250 gmall.redis.port=6379 gmall.redis.pass=Gworld2017 gmall.redis.photo.database=6 #最大分配

SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 整体思路 pomxml中加入Maven依赖 引入applicationContextxml中引入redis配置 创建缓存实现类RedisCache 创建中间类RedisCacheTransfer完成RedisCachejedisConnectionFactory的静态注入 配置文件redisproperties mapper中加入MyBatis二级缓存 Mybatis全局配置 打印Sql日志方便测试 测试代码 项目环境: 在

SpringMVC +Spring + MyBatis + Mysql + Redis(作为二级缓存) 配置

转载:http://blog.csdn.net/xiadi934/article/details/50786293 项目环境: 在SpringMVC +Spring + MyBatis + MySQL.Redis部署在Linux虚拟机. 1.整体思路 参考Ehcache实现MyBatis二级缓存代码(Maven引用对应jar查阅) 使用Spring管理Redis连接池 模仿EhcacheCache,实现RedisCache 2.pom.xml中加入Maven依赖 1 <!-- spring-re

mybatis整合Redis实现二级缓存

Mybatis整合ehcache实现二级缓存 导入相关依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!--mybatis与ehcache整合--

redis实现二级缓存

缓存的作用就是降低数据库的使用率,来减轻数据库的负担.我们平常的操作一般都是查>改,所以数据库的有些查操作是重复的,如果一直使用数据库就会有负担.Mybatis也会做缓存,也会有一级缓存和二级缓存: 一级缓存:是SqlSession级别的缓存,使用HashMap数据结构来用于存储缓存数据的 二级缓存:是mapper级别的缓存,其作用域是mapper的同一个namespace,不同的SqlSession执行两次相同namespace下的sql语句,并且传递的参数相同,返回的结果也相同时,第一次执行

【MyBatis学习13】MyBatis中的二级缓存

1. 二级缓存的原理 前面介绍了,mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的.为了更加清楚的描述二级缓存,先来看一个示意图: 从图中可以看出: sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到该UserMapper的二级缓存中. 如果SqlSession3去执行相同 mapper下sql,执行commit提交,则会清空该UserMapper下二级缓

Mybatis学习笔记-二级缓存

~ 缓存是提供应用系统性能的重要手段,前面已经介绍过Mybatis是一级缓存,与一级缓存不同的是,二级缓存的作用范围扩大到了应用级别,并且可以比一级缓存更细粒度的对二级缓存的应用进行配置.下面就详细叙述一下Mybatis的二级缓存实现. 二级缓存的工作流程 不多说,先上图,图解是攻城狮最好的朋友^_^- 前面在叙述一级缓存的时候已经说过,一级缓存是一块放在Executor中的map内存块.试想一下,如果二级缓存也是Executor中的内存块可以可以呢?-- 当然不可以!为啥?因为二级缓存要支持细

MySQL与Redis实现二级缓存

redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用 Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储 Redis支持数据的备份,即master-slave模式的数据备份 优势 性能极高 - Redis能读的速度是110

mybatis结合redis实战二级缓存(六)

之前的文章中我们意见分析了一级缓存.二级缓存的相关源码和基本原理,今天我们来分享下了mybatis二级缓存和redis的结合,当然mybatis二级缓存也可以和ehcache.memcache.OSCache.Hazelcast结合使用.二级缓存相关的源码分享请参考<Mybatis源码分析之Cache二级缓存原理>.我们通过两种方式来实战,一种是自己编写缓存.另外一种是官方给出的demo地址:http://www.mybatis.org/redis-cache/ 一:自定义mybatis缓存