在mybatis中,有一级缓存和二级缓存的概念:

一级缓存:一级缓存 Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQLSession, Mabits默认开启一级缓存。在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。

这么设计的原因是避免读取脏数据:假设A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。

二级缓存:二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。 第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。

看概念什么的最烦了是不是?用代码看看呗:

  1. package top.bigking;
  2.  
  3. import org.apache.ibatis.io.Resources;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  7. import top.bigking.dao.DeptMapper;
  8. import top.bigking.dao.UserMapper;
  9. import top.bigking.pojo.Dept;
  10. import top.bigking.pojo.User;
  11.  
  12. import java.io.InputStream;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16.  
  17. public class mybatisStudy_start {
  18. public static void main(String[] args) throws Exception{
  19. InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
  20. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  21. SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
  22. DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
  23. List<Dept> deptList = deptMapper.query();
  24. for(Dept dept : deptList){
  25. System.out.println(dept);
  26. }
  27. System.out.println("-----------------------------------");
  28. //insert(deptMapper);
  29. //update(deptMapper);
  30. findById(deptMapper);
  31.  
  32. findById(deptMapper);
  33. //delete(deptMapper);
  34. //findByIdDname(deptMapper);
  35.  
  36. // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  37. // List<User> userList = userMapper.query();
  38. // for(User user : userList)
  39. // System.out.println(user);
  40. sqlSession.close();
  41.  
  42. }
  43. private static void insert(DeptMapper deptMapper){
  44. Dept dept = new Dept();
  45. dept.setDeptNo(11);
  46. dept.setDname("ABKing");
  47. dept.setLoc("111");
  48. int count = deptMapper.insert(dept);
  49. System.out.println(count);
  50. }
  51. public static void update(DeptMapper deptMapper){
  52. Dept dept = new Dept();
  53. dept.setDeptNo(11);
  54. dept.setDname("ABKing");
  55. dept.setLoc("上海");
  56. int count = deptMapper.update(dept);
  57. System.out.println(count);
  58. }
  59. public static void findById(DeptMapper deptMapper){
  60. Dept dept = deptMapper.findById(11);
  61. System.out.println(dept);
  62. }
  63. public static void delete(DeptMapper deptMapper){
  64. int count = deptMapper.delete(11);
  65. System.out.println(count);
  66. }
  67. public static void findByIdDname(DeptMapper deptMapper){
  68. Map map = new HashMap();
  69. map.put("deptNo", "11");
  70. map.put("dname", "ABKing");
  71. Dept dept = deptMapper.findByIdDname(map);
  72. System.out.println(dept);
  73. }
  74. }

看30行和32行,能看到调用了两次findById(deptMapper),运行,查看控制台的日志(需要log4j包)

  1. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?

只打印出了一条SQL语句

而如果我们在31行加入sqlSession.clearCache();

  1. package top.bigking;
  2.  
  3. import org.apache.ibatis.io.Resources;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  7. import top.bigking.dao.DeptMapper;
  8. import top.bigking.dao.UserMapper;
  9. import top.bigking.pojo.Dept;
  10. import top.bigking.pojo.User;
  11.  
  12. import java.io.InputStream;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16.  
  17. public class mybatisStudy_start {
  18. public static void main(String[] args) throws Exception{
  19. InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
  20. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  21. SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
  22. DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
  23. List<Dept> deptList = deptMapper.query();
  24. for(Dept dept : deptList){
  25. System.out.println(dept);
  26. }
  27. System.out.println("-----------------------------------");
  28. //insert(deptMapper);
  29. //update(deptMapper);
  30. findById(deptMapper);
  31. sqlSession.clearCache();
  32. findById(deptMapper);
  33. //delete(deptMapper);
  34. //findByIdDname(deptMapper);
  35.  
  36. // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  37. // List<User> userList = userMapper.query();
  38. // for(User user : userList)
  39. // System.out.println(user);
  40. sqlSession.close();
  41.  
  42. }
  43. private static void insert(DeptMapper deptMapper){
  44. Dept dept = new Dept();
  45. dept.setDeptNo(11);
  46. dept.setDname("ABKing");
  47. dept.setLoc("111");
  48. int count = deptMapper.insert(dept);
  49. System.out.println(count);
  50. }
  51. public static void update(DeptMapper deptMapper){
  52. Dept dept = new Dept();
  53. dept.setDeptNo(11);
  54. dept.setDname("ABKing");
  55. dept.setLoc("上海");
  56. int count = deptMapper.update(dept);
  57. System.out.println(count);
  58. }
  59. public static void findById(DeptMapper deptMapper){
  60. Dept dept = deptMapper.findById(11);
  61. System.out.println(dept);
  62. }
  63. public static void delete(DeptMapper deptMapper){
  64. int count = deptMapper.delete(11);
  65. System.out.println(count);
  66. }
  67. public static void findByIdDname(DeptMapper deptMapper){
  68. Map map = new HashMap();
  69. map.put("deptNo", "11");
  70. map.put("dname", "ABKing");
  71. Dept dept = deptMapper.findByIdDname(map);
  72. System.out.println(dept);
  73. }
  74. }

此时查看控制台的日志

  1. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?
  2. DEBUG [main] - ==> Parameters: 11(Integer)
  3. DEBUG [main] - <== Total: 1
  4. Dept{deptNo=11, dname='ABKing', loc='111'}
  5. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?

可以看到打印出了两条SQL语句,这足以证明,使用了sqlSession.clearCache();之后,缓存被清空了

接下来证明二级缓存:

应当明确的是,二级缓存是mapper级别的缓存,使用同一个Mapper.class的的Mapper类和SqlSession类都共用同一个二级缓存

代码如下:

  1. package top.bigking;
  2.  
  3. import org.apache.ibatis.io.Resources;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  7. import top.bigking.dao.DeptMapper;
  8. import top.bigking.dao.UserMapper;
  9. import top.bigking.pojo.Dept;
  10. import top.bigking.pojo.User;
  11.  
  12. import java.io.InputStream;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16.  
  17. public class mybatisStudy_start {
  18. public static void main(String[] args) throws Exception{
  19. InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
  20. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
  21. SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
  22. SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
  23. DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
  24. DeptMapper deptMapper1 = sqlSession1.getMapper(DeptMapper.class);
  25. List<Dept> deptList = deptMapper.query();
  26. for(Dept dept : deptList){
  27. System.out.println(dept);
  28. }
  29. System.out.println("-----------------------------------");
  30. //insert(deptMapper);
  31. //update(deptMapper);
  32. findById(deptMapper);
  33. sqlSession.close();
  34. //sqlSession.clearCache();
  35. findById(deptMapper1);
  36. sqlSession1.close();
  37. //delete(deptMapper);
  38. //findByIdDname(deptMapper);
  39.  
  40. // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  41. // List<User> userList = userMapper.query();
  42. // for(User user : userList)
  43. // System.out.println(user);
  44. //sqlSession.close();
  45.  
  46. }
  47. private static void insert(DeptMapper deptMapper){
  48. Dept dept = new Dept();
  49. dept.setDeptNo(11);
  50. dept.setDname("ABKing");
  51. dept.setLoc("111");
  52. int count = deptMapper.insert(dept);
  53. System.out.println(count);
  54. }
  55. public static void update(DeptMapper deptMapper){
  56. Dept dept = new Dept();
  57. dept.setDeptNo(11);
  58. dept.setDname("ABKing");
  59. dept.setLoc("上海");
  60. int count = deptMapper.update(dept);
  61. System.out.println(count);
  62. }
  63. public static void findById(DeptMapper deptMapper){
  64. Dept dept = deptMapper.findById(11);
  65. System.out.println(dept);
  66. }
  67. public static void delete(DeptMapper deptMapper){
  68. int count = deptMapper.delete(11);
  69. System.out.println(count);
  70. }
  71. public static void findByIdDname(DeptMapper deptMapper){
  72. Map map = new HashMap();
  73. map.put("deptNo", "11");
  74. map.put("dname", "ABKing");
  75. Dept dept = deptMapper.findByIdDname(map);
  76. System.out.println(dept);
  77. }
  78. }

在DeptMapper.xml中

  1. <select id="findById" resultType="Dept" useCache="true">
  2. select deptNo, dname, loc from Dept where deptNo=#{deptNo}
  3. </select>

通过useCache可以使用二级缓存

在mybatisStudy-config.xml中,在properties标签下,添加

  1. <settings>
  2. <setting name="cacheEnabled" value="true"/>
  3. </settings>

这是全局设置,表示开启二级缓存

查看控制台输出的日志:

  1. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?
  2. DEBUG [main] - ==> Parameters: 11(Integer)
  3. DEBUG [main] - <== Total: 1
  4. Dept{deptNo=11, dname='ABKing', loc='111'}
  5. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]

可以看到,由于使用了二级缓存,我们的日志中,只出现了一条SQLQL语句

而如果我们把DeptMapper.xml中的代码改为:

  1.   <select id="findById" resultType="Dept" useCache="false">
  2. select deptNo, dname, loc from Dept where deptNo=#{deptNo}
  3. </select>

表示不使用二级缓存

运行,查看控制台:

  1. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?
  2. DEBUG [main] - ==> Parameters: 11(Integer)
  3. DEBUG [main] - <== Total: 1
  4. Dept{deptNo=11, dname='ABKing', loc='111'}
  5. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]
  6. DEBUG [main] - Returned connection 2056418216 to pool.
  7. DEBUG [main] - Opening JDBC Connection
  8. DEBUG [main] - Checked out connection 2056418216 from pool.
  9. DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?
  10. DEBUG [main] - ==> Parameters: 11(Integer)
  11. DEBUG [main] - <== Total: 1
  12. Dept{deptNo=11, dname='ABKing', loc='111'}
  13. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]

可以看到两条SQL语句

可是我们的代码中,并没有使用到清空一级缓存的函数sqlSession.clearCache();

由此可证明,这里是二级缓存的开关

参考:

https://m.w3cschool.cn/kzsow/kzsow-qmod2gri.html

https://www.cnblogs.com/happyflyingpig/p/7739749.html

https://www.cnblogs.com/yuluoxingkong/p/8205858.html

https://www.cnblogs.com/charlypage/p/9747145.html

----------------------------------------------------------------------------
大家好,我是ABKing

金麟岂是池中物,一遇风云便化龙!
欢迎与我交流技术问题

mybatis一级缓存和二级缓存的使用的更多相关文章

  1. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  2. MyBatis 延迟加载,一级缓存,二级缓存设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

  3. mybatis高级(3)_延迟加载_深度延迟_一级缓存_二级缓存

    设置延迟加载需要在mybatis.xml中设置 注: 侵入式延迟加载为真时是延迟加载 侵入式延迟加载为假时是深度延迟加载 <!-- 延迟加载和深度延迟加载 --> <settings ...

  4. 9.Mybatis一级缓存和二级缓存

    所谓的缓存呢?其实原理很简单,就是在保证你查询的数据是正确的情况下,没有去查数据库,而是直接查找的内存,这样做有利于缓解数据库的压力,提高数据库的性能,Mybatis中有提供一级缓存和二级缓存. 学习 ...

  5. 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合

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

  6. myBatis学习(9):一级缓存和二级缓存

    正如大多数持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持 1. MyBatis一级缓存基于PerpetualCache的HashMap本地缓存,其存储作用域为 Session,默认情 ...

  7. mybatis 详解(九)------ 一级缓存、二级缓存

    上一章节,我们讲解了通过mybatis的懒加载来提高查询效率,那么除了懒加载,还有什么方法能提高查询效率呢?这就是我们本章讲的缓存. mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解 ...

  8. MyBatis从入门到放弃六:延迟加载、一级缓存、二级缓存

    前言 使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMa ...

  9. Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】

    Mybatis缓存 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. myba ...

  10. MyBatis 一级缓存,二级缓存,延迟加载设置

       1  什么是延迟加载  resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再 ...

随机推荐

  1. MySQL优化建议与使用规范

    适用场景:并发量大.数据量大的互联网业务;可以先阅读必须掌握的MySQL优化指南 一.基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务.行级锁.并发性能更好.CPU及内存缓存页优化使得资源 ...

  2. 【POJ2486】Apple Tree

    题目大意:给定一棵 N 个节点的有根树,点有点权,边权均为1.现允许从根节点出发走 K 步,求可以经过的点权之和最大是多少. 题解:可以将点权看作是价值,将可以走的步数看作是重量,则转化成了一个树上背 ...

  3. 【转】H5 浏览器和 webview 后退缓存机制

    来源:https://juejin.im/entry/588b44a08fd9c544813ed5b3 一.背景 用户点击浏览器工具栏中的后退按钮,或者移动设备上的返回键时,或者JS执行history ...

  4. thinkphp查询构造器和链式操作、事务

    插入 更新记录 查询数据 删除数据 插入数据----name这种用法,会去config.php中去寻找前缀,如果你定义了前缀tp,那么执行下条语句会查询对tp_data的插入操作 链式操作---> ...

  5. 算法复习-a 到 z不完全排列生成

    在网上看到这个题,觉得很有意思,也算是一种方法...但是复杂度同样很高,生成全排列本身需要很大复杂度. 题目:现在有 a 到 z 26 个元素, 编写程序打印 a 到 z 中任取 3 个元素的组合(比 ...

  6. SDRAM学习笔记

    摘自“开源骚客视频教程” 1.仲裁模块就是用来控制什么时候读.写.刷新 2.模块中的状态机 3.初始化时序图说明,来自“IS42S116160.pdf”文件 4.SDRAM写时序图,来自“IS42S1 ...

  7. SQLite为何要用C语言来开发?

    SQLite 选择 C 语言的理由是?为什么不选择 Go 或者 Rust? C 语言是最好的 SQLite 在 2000 年 5 月 29 日发布,并一直使用 C 语言实现.C 语言一直是实现 SQL ...

  8. 2019hdu多校 Fansblog

    Problem Description Farmer John keeps a website called 'FansBlog' .Everyday , there are many people ...

  9. 打开ubuntu终端,没有用户名显示,只剩下光标在闪

    总结起来就是bash损坏了.bash是用户与操作系统内核交互的工具.bash损坏,则用户无法操作计算机. 推荐两个帖子: https://blog.csdn.net/u011128515/articl ...

  10. Oracle-SYSTEM表空间突然持续爆满

    一般情况下,我们建完数据库后,都会给数据库指定一个新的默认表空间,不然会占用数据库系统表空间资源,导致数据库性能下降. 我们可以同过SQL语句找出改表空间占用空间前10的对象 SELECT * FRO ...