正如大多数持久层框架一样,MyBatis 同样提供了一级缓存二级缓存的支持。

1.缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

mybatis的一级缓存作用就是在同一个session过程中,将会对相同数据的存取不通过数据库,而是通过缓存机制提高效率,看测试代码
<img src="https://pic3.zhimg.com/50/c225e22b0d00f5903b3626009228767e_hd.jpg" data-rawwidth="307" data-rawheight="347" class="content_image" width="307">

import java.io.IOException;
import java.io.InputStream;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import com.guowuxin.mybatis.mapper.UserMapper;
import com.guowuxin.mybatis.model.User;/*用户表
drop table if exists user;
create table user(id int primary key auto_increment,username varchar(50) unique,password varchar(100),useraddress varchar(50)
);
insert into user values(1,"guowuxin","guowuxin","beijing");
insert into user values(1,"guoxiaoming","guowuxin","beijing");
*///如果两次查询都是查询1 将只会发送一条sql语句到数据库,否则将是2条sql语句public class TestClass extends TestCase{public static SqlSessionFactory sqlSessionFactoy;static{String resource = "mybatis-config.xml";try {InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactoy = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}@Test public void testgetUserById() { SqlSession sqlSession = sqlSessionFactoy.openSession(); try { UserMapper mapper = sqlSession.getMapper(UserMapper.class); User u1=mapper.getUserById(1);System.out.println(u1);User u2=mapper.getUserById(1);System.out.println(u2);sqlSession.commit();} finally { sqlSession.close(); } }
}

package com.guowuxin.mybatis.mapper;import com.guowuxin.mybatis.model.User;//通过面向接口的mybatis编程方式,需要保证方法名和配置文件中的id名称一致
public interface UserMapper {public User getUserById(int id);
}

package com.guowuxin.mybatis.model;public class User {private int id;private int age;private String userName;private String userAddress;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserAddress() {return userAddress;}public void setUserAddress(String userAddress) {this.userAddress = userAddress;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString(){final StringBuilder builder = new StringBuilder();builder.append("id=").append(id).append(",");builder.append("age=").append(age).append(",");builder.append("userName=").append(userName).append(",");builder.append("userAddress=").append(userAddress).append(".");return builder.toString();}
}

log4j.rootLogger=DEBUG,Console
ˆ†
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d %t %-5p (%c) - %m%nlog4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

<?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><typeAliases><typeAlias alias="User" type="com.guowuxin.mybatis.model.User" /></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED">  <property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://127.0.0.1:3306/guowuxin" /><property name="username" value="root" /><property name="password" value="admin" /></dataSource></environment></environments><mappers><mapper resource="UserMapper.xml" /></mappers></configuration>

<?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">
<!-- 这里namespace必须是PostsMapper接口的路径,不然要运行的时候要报错 “is not known to the MapperRegistry”-->
<mapper namespace="com.guowuxin.mybatis.mapper.UserMapper"> <!-- 这儿的resultType是配置在mybatis-config.xml中得别名 --><select id="getUserById" parameterType="int" resultType="User">select * from user where id=#{id}</select>
</mapper>

结果:

....................
2016-02-24 20:12:37,568 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:37,568 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==>  Preparing: select * from user where id=?
2016-02-24 20:12:37,586 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 1(Integer)
id=1,age=0,userName=guowuxin,userAddress=beijing.
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-24 20:12:37,593 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:37,593 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:37,593 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Returned connection 3874052 to pool.

如果取得2个不同的id

.......................
2016-02-24 20:12:57,655 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Created connection 3874052.
2016-02-24 20:12:57,656 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:57,656 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==>  Preparing: select * from user where id=?
2016-02-24 20:12:57,664 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 1(Integer)
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-24 20:12:57,679 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:57,679 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==>  Preparing: select * from user where id=?
2016-02-24 20:12:57,679 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 2(Integer)
id=2,age=0,userName=guoxiaoming,userAddress=beijing.
2016-02-24 20:12:57,679 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:57,679 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:12:57,679 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Returned connection 3874052 to pool.

二级缓存机制指的则是在不同的session之间都可以共享相同的数据内容。

import java.io.IOException;
import java.io.InputStream;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;import com.guowuxin.mybatis.mapper.UserMapper;
import com.guowuxin.mybatis.model.User;import junit.framework.TestCase;public class TestTwoCache extends TestCase{public static SqlSessionFactory sqlSessionFactory;static{String resource = "mybatis-config.xml";try {InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}@Test public void testCache() { SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();try { UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User u1=mapper1.getUserById(1);System.out.println(u1);sqlSession1.commit();UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);User u2=mapper2.getUserById(1);System.out.println(u2);sqlSession2.commit();} finally { sqlSession1.close(); sqlSession2.close();} }
}

在没有开启二级缓存之前,将会执行两次sql语句。
2016-02-24 20:28:10,786 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - PooledDataSource forcefully closed/removed all connections.
2016-02-24 20:28:10,850 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Openning JDBC Connection
2016-02-24 20:28:11,011 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Created connection 3874052.
2016-02-24 20:28:11,012 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:28:11,013 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Preparing: select * from user where id=?
2016-02-24 20:28:11,030 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 1(Integer)
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-24 20:28:11,040 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Openning JDBC Connection
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Created connection 29420695.
2016-02-24 20:28:11,154 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1c0ec97]
2016-02-24 20:28:11,154 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Preparing: select * from user where id=?
2016-02-24 20:28:11,154 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 1(Integer)
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@3b1d04]
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Returned connection 3874052 to pool.
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1c0ec97]
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1c0ec97]
2016-02-24 20:28:11,154 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Returned connection 29420695 to pool.

------------------------
在实体类映射文件中加入<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">
<!-- 这里namespace必须是PostsMapper接口的路径,不然要运行的时候要报错 “is not known to the MapperRegistry”-->
<mapper namespace="com.guowuxin.mybatis.mapper.UserMapper"> <!-- 这儿的resultType是配置在mybatis-config.xml中得别名 --><cache /><select id="getUserById" parameterType="int" resultType="User">select * from user where id=#{id}</select>
</mapper>

2016-02-25 10:15:11,162 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Created connection 22522451.
2016-02-25 10:15:11,164 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@157aa53]
2016-02-25 10:15:11,164 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==>  Preparing: select * from user where id=?
2016-02-25 10:15:11,182 main DEBUG (com.guowuxin.mybatis.mapper.UserMapper.getUserById) - ==> Parameters: 1(Integer)
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-25 10:15:11,196 main DEBUG (org.apache.ibatis.cache.decorators.LoggingCache) - Cache Hit Ratio [com.guowuxin.mybatis.mapper.UserMapper]: 0.5
id=1,age=0,userName=guowuxin,userAddress=beijing.
2016-02-25 10:15:11,196 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@157aa53]
2016-02-25 10:15:11,196 main DEBUG (org.apache.ibatis.transaction.jdbc.JdbcTransaction) - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@157aa53]
2016-02-25 10:15:11,197 main DEBUG (org.apache.ibatis.datasource.pooled.PooledDataSource) - Returned connection 22522451 to pool.

就会发现cache命中,只执行了一次sql语句

------------------------------
如果二级缓存想要命中实现,则必须要将上一次sqlSession commit之后才能生效,不然将不会命中,原因:
两个不同的session必须提交前面一个session才能缓存生效的原因是因为mybatis的缓存会被一个transactioncache类包装住,所有的cache.putObject全部都会被暂时存到一个map里,等事务提交以后,这个map里的缓存对象才会被真正的cache类执行putObject操作。

这么设计的原因是为了防止事务执行过程中出异常导致回滚,如果get到object后直接put进缓存,万一发生回滚,就很容易导致mybatis缓存被脏读

mybatis的缓存机制是怎么样的?相关推荐

  1. MyBatis的缓存机制详解

    MyBatis的缓存机制详解 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制,缓存可以极大的提升查询效率.MyBatis中默认定义了两级缓存,分别是一级缓存和二级缓存. ( ...

  2. MyBatis:缓存机制详解

    本篇内容包括:MyBatis 缓存机制概述.一级缓存与二级缓存的介绍.配置和具体流程. 一.MyBatis 缓存机制概述 在我们常见的 OLTP(on-line transaction process ...

  3. Hibernate和MyBatis的缓存机制和比较

    原文地址:https://my.oschina.NET/u/1445731/blog/416200?p=%7B%7BtotalPage%7D%7D Mybatis缓存 分为1级缓存和2级缓存,2级缓存 ...

  4. MyBatis之缓存机制

    缓存即为存在内存中的临时数据.将用户经常查询的数据存放在缓存(内存)中,用户去查询数据就不用去每次去数据库中查询,而是去缓存中查询,从而提高了查询的效率,解决了高并发系统的性能问题.MyBatis提供 ...

  5. 11【MyBatis的缓存机制】

    文章目录 二.Mybatis缓存机制 2.1 缓存介绍 2.2 一级缓存 2.2.1 一级缓存相关参数 2.2.2 一级缓存测试 2.2.3 一级缓存清空 2.2.3.1 设置localCacheSc ...

  6. (十二)Mybatis的缓存机制

    文章目录 环境 Mybatis的缓存 一级缓存 一级缓存失效 方式一 方式二 二级缓存 MyBatis集成EhCache缓存 Mybatis学习目录 上一篇:(十一)MyBatis的高级映射及延迟加载 ...

  7. mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache

    1      查询缓存 1.1  什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在 ...

  8. 框架:mybatis的缓存机制

    一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据.不同的sqlSession之间的缓存数 ...

  9. Mybatis的缓存机制Cache

    Mybatis提供对缓存的支持,分为一级缓存和二级缓存,在没有配置的情况下,系统默认会使用一级缓存. 一级缓存(SqlSession级别) 我们都知道每个SqlSession对象之间的缓存是互不影响的 ...

最新文章

  1. 第四周实践项目7 多项式求和
  2. 微软一顿操作猛如虎,PowerShell 排名直线上升
  3. mysql数据加百分号_使用MySQL SELECT语句时,在每个值的末尾添加一个百分号(%)...
  4. Linux中g++与gcc的区别
  5. 计算机老师任课教师寄语,任课老师寄语大全
  6. 每日一题 2020.05.12
  7. 产生随机小数_如果取到小数区间内的任一数字?
  8. 如何写_家长如何为老师写评语
  9. Docker入坑指南之EXEC
  10. ERROR: libx264 not found
  11. 测评两款升压稳压芯片
  12. 哪种程序员最挣钱?平均月薪30.8K,网友说这是掌握世界的技术
  13. Codeforces 1379B.Dubious Cyrpto
  14. 12年时记录的一堆杂事
  15. kubernetes中metrics-server与HPA
  16. ASP.Net中常见的文件类型
  17. 【ORA-00257:archiver error. Connect internal only, until freed;清理归档日志】
  18. 首页滑滑滑,支付宝穿越回年轻样子
  19. 这几年已经组织开发或者即将开发我的或与我有关的第7个薪资管理系统、第5个人事管理系统,从中你觉得啥才真正值钱?...
  20. Mysql 知行必会 “子查询”

热门文章

  1. mat 内存分析 Linux,JVM内存分析工具MAT使用简介
  2. oracle 8i漏洞渗透,一次通过Oracle8i入侵系统之旅(组图)
  3. 设无向图g如图所示_阿里重磅发布大规模图神经网络平台 AliGraph,架构算法解读...
  4. 云桌面部署_东胜区检察院检察工作网统一业务系统2.0云桌面终端全面部署完成...
  5. ssd训练自己数据集
  6. 数据结构-队列1-顺序存储
  7. linux如何安装python环境变量中,Windows和linux环境下python安装及环境变量的配置
  8. 交流充电桩电路图_直流充电桩和交流充电桩给电动汽车充电过程中是如何工作的?...
  9. ❤️震惊!人生苦短,我用python来玩田忌赛马❤️
  10. 如何获取codeforces的完整数据