http://blog.csdn.net/weixin_36380516/article/details/73194758
 
先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。
 
一级缓存
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的。
 
一级缓存的工作原理:
 
用户发起查询请求,查找某条数据,sqlSession先去缓存中查找,是否有该数据,如果有,读取;
如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。
但sqlSession执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。
如果commit不清空缓存,会有以下场景:A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。
既然有了一级缓存,那么为什么要提供二级缓存呢?
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。
还有一个原因,实际开发中,MyBatis通常和Spring进行整合开发。Spring将事务放到Service中管理,对于每一个service中的sqlsession是不同的,这是通过mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。
 
二级缓存
二级缓存原理:
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
UserMapper有一个二级缓存区域(按namespace分),其它mapper也有自己的二级缓存区域(按namespace分)。每一个namespace的mapper都有一个二级缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同的二级缓存区域中。
开启二级缓存:
1,打开总开关
在MyBatis的配置文件中加入:
  1. <span style="font-size:18px;"><settings>
  2. <!--开启二级缓存-->
  3. <setting name="cacheEnabled" value="true"/>
  4. </settings> </span>
2,在需要开启二级缓存的mapper.xml中加入caceh标签
  1. <span style="font-size:18px;"><cache/></span>
3,让使用二级缓存的POJO类实现Serializable接口
  1. <span style="font-size:18px;">public class User implements Serializable {}</span>
 
测试一下
  1. <span style="font-size:18px;">@Test
  2. public void testCache2() throws Exception {
  3. SqlSession sqlSession1 = sqlSessionFactory.openSession();
  4. SqlSession sqlSession2 = sqlSessionFactory.openSession();
  5. UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  6. User user1 = userMapper1.findUserById(1);
  7. System.out.println(user1);
  8. sqlSession1.close();
  9. UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  10. User user2 = userMapper2.findUserById(1);
  11. System.out.println(user2);
  12. sqlSession2.close();
  13. }</span>
输出结果:
  1. <span style="font-size:18px;">DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.0
  2. DEBUG [main] - Opening JDBC Connection
  3. DEBUG [main] - Created connection 103887628.
  4. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  5. DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE id=?
  6. DEBUG [main] - ==> Parameters: 1(Integer)
  7. DEBUG [main] - <==      Total: 1
  8. User [id=1, username=张三, sex=1, birthday=null, address=null]
  9. DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  10. DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c]
  11. DEBUG [main] - Returned connection 103887628 to pool.
  12. DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.5
  13. User [id=1, username=张三, sex=1, birthday=null, address=null]</span>
我们可以从打印的信息看出,两个sqlSession,去查询同一条数据,只发起一次select查询语句,第二次直接从Cache中读取。
 
前面我们说到,Spring和MyBatis整合时, 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。那么如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。
 
总结:
对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。
 
但不能滥用二级缓存,二级缓存也有很多弊端,从MyBatis默认二级缓存是关闭的就可以看出来。
二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。
举个简单的例子:
订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。
 
根据以上,想要使用二级缓存时需要想好两个问题:
1)对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。
2)对关联表的查询,关联的所有表的操作都必须在同一个namespace。
 
http://www.360doc.com/content/15/1205/07/29475794_518018352.shtml
https://www.cnblogs.com/cuibin/articles/6827116.html
http://blog.csdn.net/u013036274/article/details/55815104

深入理解MyBatis中的一级缓存与二级缓存的更多相关文章

  1. Mybatis的一级缓存和二级缓存的理解以及用法

    程序中为什么使用缓存? 先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术.对于我们编程来说,所谓的 ...

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

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

  3. 关于mybatis中一级缓存和二级缓存的简单介绍

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

  4. 【MyBatis学习12】MyBatis中的一级缓存

    缓存的作用是减轻数据库的压力,提高数据库的性能的.mybatis中提供了一级缓存和二级缓存,先来看一下两个缓存的示意图:   从图中可以看出: 一级缓存是SqlSession级别的缓存.在操作数据库时 ...

  5. 阶段3 1.Mybatis_11.Mybatis的缓存_6 Mybatis中的一级缓存

    Mybatis中的一级缓存和二级缓存         一级缓存:             它指的是Mybatis中SqlSession对象的缓存.             当我们执行查询之后,查询的结 ...

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

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

  7. 0065 MyBatis一级缓存与二级缓存

    数据库中数据虽多,但访问频率却不同,有的数据1s内就会有多次访问,而有些数据几天都没人查询,这时候就可以将访问频率高的数据放到缓存中,就不用去数据库里取了,提高了效率还节约了数据库资源 MyBatis ...

  8. MyBatis 系列五 之 延迟加载、一级缓存、二级缓存设置

    MyBatis的延迟加载.一级缓存.二级缓存设置 首先我们必须分清延迟加载的适用对象 延迟加载 MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟加载规则推迟对关联对象的se ...

  9. MyBatis 一级缓存、二级缓存全详解(一)

    目录 MyBatis 一级缓存.二级缓存全详解(一) 什么是缓存 什么是MyBatis中的缓存 MyBatis 中的一级缓存 初探一级缓存 探究一级缓存是如何失效的 一级缓存原理探究 还有其他要补充的 ...

随机推荐

  1. 20145122《JAVA开发环境的熟悉》实验报告

    package fib; public class fibonaci { public static void main(String[] args) { Fibonaci(20); } public ...

  2. Online Judge 2014 K-th Number -主席树

    You are working for Macrohard company in data structures department. After failing your previous tas ...

  3. jz2440移植QT5.6【学习笔记】【原创】

    平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 交叉编译工具:arm-linux-gcc (GCC)4.4.3 linux:linu3.4.2 PC环境:ubuntu18.04 一.修改/o ...

  4. cygwin下使用apt-cyg安装新软件

    1.获取  (记得先安装好git) git clone https://github.com/transcode-open/apt-cyg.git 2.安装apt-cyg cd apt-cyg chm ...

  5. FJNUOJ the greed of Yehan(最长路 + 权值乘积转化)题解

    Description During the trip, Yehan and Linlin pass a cave, and there is a board at the door, which s ...

  6. UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解

    思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Krus ...

  7. LOJ #10222. 「一本通 6.5 例 4」佳佳的 Fibonacci

    题目链接 题目大意 $$F[i]=F[i-1]+F[i-2]\ (\ F[1]=1\ ,\ F[2]=1\ )$$ $$T[i]=F[1]+2F[2]+3F[3]+...+nF[n]$$ 求$T[n] ...

  8. java web项目配置https访问

      转载: tomcat6配置:  1.单向认证,就是传输的数据加密过了,但是不会校验客户端的来源  2.双向认证,如果客户端浏览器没有导入客户端证书,是访问不了web系统的,找不到地址  如果只是加 ...

  9. idea oracle反向工程生成实体类

    1. 选择View-Tool Window- Database 2. 配置数据库信息 提示:配置完成后可以通过idea进行sql查询等操作 3.在项目中创建hbernate.cfg.xml文件, 在r ...

  10. python 中的object与type的关系

    object 和 type的关系很像鸡和蛋的关系,先有object还是先有type没法说,obejct和type是共生的关系,必须同时出现的. 在看下去之前,也要请先明白,在Python里面,所有的东 ...