Redis实现Mybatis的二级缓存
一、Mybatis的缓存
通大多数ORM层框架一样,Mybatis自然也提供了对一级缓存和二级缓存的支持。一下是一级缓存和二级缓存的作用于和定义。
1、一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
2、一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写 到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存 也就不存在了。Mybatis默认开启一级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同 namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二 次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
一般的我们将Mybatis和Spring整合时,mybatis-spring包会自动分装sqlSession,而Spring通过动态代理 sqlSessionProxy使用一个模板方法封装了select()等操作,每一次select()查询都会自动先执行openSession(), 执行完close()以后调用close()方法,相当于生成了一个新的session实例,所以我们无需手动的去关闭这个session(),当然也无 法使用mybatis的一级缓存,也就是说mybatis的一级缓存在spring中是没有作用的。
因此我们一般在项目中实现Mybatis的二级缓存,虽然Mybatis自带二级缓存功能,但是如果实在集群环境下,使用自带的二级缓存只是针对单个的节 点,所以我们采用分布式的二级缓存功能。一般的缓存NoSql数据库如redis,Mancache等,或者EhCache都可以实现,从而更好地服务 tomcat集群中ORM的查询。
二、Mybatis的二级缓存的实现
下面主要通过Redis实现Mybatis的二级缓存功能。
1、配置文件中开启二级缓存
- <setting name="cacheEnabled" value="true"/>
默认二级缓存是开启的。
2、实现Mybatis的Cache接口
Mybatis提供了第三方Cache实现的接口,我们自定义MybatisRedisCache实现Cache接口,代码如下:
- /**
- * 创建时间:2016年1月7日 上午11:40:00
- *
- * Mybatis二级缓存实现类
- *
- * @author andy
- * @version 2.2
- */
- public class MybatisRedisCache implements Cache {
- private static final Logger LOG = Logger.getLogger(MybatisRedisCache.class);
- private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
- private RedisTemplate<Serializable, Serializable> redisTemplate = (RedisTemplate<Serializable, Serializable>) SpringContextHolder.getBean("redisTemplate");
- private String id;
- private JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();
- public MybatisRedisCache(final String id){
- if(id == null){
- throw new IllegalArgumentException("Cache instances require an ID");
- }
- LOG.info("Redis Cache id " + id);
- this.id = id;
- }
- @Override
- public String getId() {
- return this.id;
- }
- @Override
- public void putObject(Object key, Object value) {
- if(value != null){
- redisTemplate.opsForValue().set(key.toString(), jdkSerializer.serialize(value), 2, TimeUnit.DAYS);
- }
- }
- @Override
- public Object getObject(Object key) {
- try {
- if(key != null){
- Object obj = redisTemplate.opsForValue().get(key.toString());
- return jdkSerializer.deserialize((byte[])obj);
- }
- } catch (Exception e) {
- LOG.error("redis ");
- }
- return null;
- }
- @Override
- public Object removeObject(Object key) {
- try {
- if(key != null){
- redisTemplate.expire(key.toString(), 1, TimeUnit.SECONDS);
- }
- } catch (Exception e) {
- }
- return null;
- }
- @Override
- public void clear() {
- //jedis nonsupport
- }
- @Override
- public int getSize() {
- Long size = redisTemplate.getMasterRedisTemplate().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、二级缓存的实用
我们需要将所有的实体类进行序列化,然后在Mapper中添加自定义cache功能。
- <cache
- type="org.andy.shop.cache.MybatisRedisCache"
- eviction="LRU"
- flushInterval="6000000"
- size="1024"
- readOnly="false"
- />
4、Redis中的存储
redis会自动的将Sql+条件+Hash等当做key值,而将查询结果作为value,只有请求中的所有参数都符合,那么就会使用redis中的二级缓存。其查询结果如下:
Redis实现Mybatis的二级缓存的更多相关文章
- 使用Redis做MyBatis的二级缓存
使用Redis做MyBatis的二级缓存 通常为了减轻数据库的压力,我们会引入缓存.在Dao查询数据库之前,先去缓存中找是否有要找的数据,如果有则用缓存中的数据即可,就不用查询数据库了. 如果没有才去 ...
- MyBatis:二级缓存原理分析
MyBatis从入门到放弃七:二级缓存原理分析 前言 说起mybatis的一级缓存和二级缓存我特意问了几个身边的朋友他们平时会不会用,结果没有一个人平时业务场景中用. 好吧,那我暂且用来学习源码吧.一 ...
- redis学习总结-redis作为MyBatis的自定义缓存
1.RedisCache.java package com.houtai.cache; import java.util.concurrent.locks.ReadWriteLock; import ...
- Mybatis的二级缓存配置
一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的. Mybatis的二级缓存配置相当容易,要开启二级缓存,只需要在你的 ...
- Mybatis的二级缓存注意点
--声明:一下内容都不一定是正确的,只是自己测试的结果,请自己的动手操作得出自己的结论 1.开启Mybatis的二级缓存,不仅要在SqlMapConfig.xml中进行开启总开关,还要在对应的XXXM ...
- mybatis开启二级缓存小记
mybatis开启二级缓存小记 1.开启二级缓存 和一级缓存默认开启不一样,二级缓存需要我们手动开启 首先在全局配置文件 mybatis-configuration.xml 文件中加入如下代码: &l ...
- 《深入理解mybatis原理7》 MyBatis的二级缓存的设计原理
<深入理解mybatis原理> MyBatis的二级缓存的设计原理 MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分 ...
- 《深入理解mybatis原理》 MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 如上图所示,当开一个会话时,一个SqlS ...
- mybatis深入理解(六)-----MyBatis的二级缓存的设计原理
MyBatis的二级缓存是Application级别的缓存,它可以提高对数据库查询的效率,以提高应用的性能.本文将全面分析MyBatis的二级缓存的设计原理. 1.MyBatis的缓存机制整体设计以及 ...
随机推荐
- 洛谷 P1719 最大加权矩形
P1719 最大加权矩形 题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她 ...
- 具体解释NoSQL数据库使用实例
一.NoSQL基础知识 1.关于NoSQL 在"NoSQL"一词.实际上是一个叫Racker的同事创造的,当约翰埃文斯埃里克要组织一次活动来讨论开源的分布式数据库. 这个名称和概念 ...
- Linux中 ps aux 命令
$ ps aux USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 11 100.0 0.0 0 16 ?? RL 4Dec09 ...
- Effective C++ Item 38 通过复合塑模出 has-a 或 is-implemented-in-terms-of
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:在应用域,复合意味着 has-a. 在实现域.复合意味着 is-implemented ...
- [ Javascript ] JavaScript中的定时器(Timer) 是怎样工作的!
作为入门者来说.了解JavaScript中timer的工作方式是非常重要的.通常它们的表现行为并非那么地直观,而这是由于它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. ...
- a标签中的javascript:;是什么
a标签中的javascript:;是什么 一.问题 <a>标签中href="javascript:;"表示什么意思?? <a id="jsPswEdit ...
- 项目: 基于Python socket模块实现的简单 ftp 项目:
需要 自己创建一个 info 文件 用来存储用户信息 服务器: import socket import pickle import struct import os import time ''.s ...
- ElasticSearch、Kibana Web管理
ElasticSearch的Web管理 http://localhost:9200/ http://localhost:9200/cluster/health?pretty http://localh ...
- javafx Hanoi
Netbean java8 source code :http://files.cnblogs.com/files/rojas/HNT.zip screenshot: 1 model /* ...
- vue 中表单 [v-bind:true-value="a" v-bind:false-value="b"] 的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...