程序中为什么使用缓存?
   实际上适用于缓存的数据:经常查询并且不经常改变的,并且的数据的正确与否对最终结果影响不大的、不适用于缓存的数据:经常改变的数据,数据的正确与否对最终
结果影响很大的。
Mybatis中的一级缓存和二级缓存到底缓存了什么,缓存了以后又有什么效果,缓存的数据什么时候会被清空?
  一级缓存:它指的是Mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入到SqlSession为我们提供的一块区域中,该区域的结构是一个Map,当我们再次查询同样的数据,mybatis会
先去sqlsession中查询是否有,的话直接拿出来用,当SqlSession对象消失时,mybatis的一级缓存也就消失了,同时一级缓存是SqlSession范围的缓存,当调用SqlSession的修改、添加、删除、commit(),close等
方法时,就会清空一级缓存。
  二级缓存:他值得是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其缓存,但是其中缓存的是数据而不是对象,所以从二级缓存再次查询出得结果的对象与
第一次存入的对象是不一样的。
  通过简单的例子来加深理解一级缓存和二级缓存。
一级缓存
1.用户类

public class User implements Serializable{private Integer id;private String username;private Date birthday;private String sex;private String address;get和set方法省略.....
}

2.Dao层

public interface UserDao {/*** 查询所有的用户** @return*/List<User> findAll();/*** 根据Id查询用户** @return*/User findById(Integer id);/*** 更新用户* @param user*/void updateUser(User user);

3.UserDao.xml映射文件

<mapper namespace="com.example.dao.UserDao"><select id="findAll" resultType="com.example.domain.User">SELECT * FROM USER;</select><select id="findById" resultType="com.example.domain.User" parameterType="INT">SELECT * FROM  USER  WHERE ID = #{ID}</select><update id="updateUser" parameterType="com.example.domain.User">update USER<set><if test="username != null">username=#{username},</if><if test="password != null">birthday=#{birthday},</if><if test="sex != null">sex=#{sex},</if><if test="address != null">address=#{address},</if></set>where id=#{id}</update>
</mapper>

在以上三步中这是mybatis的单表操作,下面通过根据用户ID查询用户的操作来观察一级缓存生效与否的区别

4.测试
(1) 命中一级缓存的情况
测试代码:

@Testpublic void findByIdTest(){session = factory.openSession();userDao = session.getMapper(UserDao.class);//第一次获取该用户User user1 = userDao.findById(45);System.out.println(user1);第二次获取该用户User user2 = userDao.findById(45);System.out.println(user2);System.out.println(user1 == user2);session.close();}  

测试结果:

(2)对SqlSession进行清除缓存的操作,即清楚一级缓存,然后再次进行测试。

@Testpublic void findByIdTest(){session = factory.openSession();userDao = session.getMapper(UserDao.class);User user1 = userDao.findById(45);System.out.println(user1);//       session.commit(); 调用SqlSession的commit方法清空缓存user1.setUsername("更新用户");user1.setAddress("更新地址");userDao.updateUser(user1);//通过更新SqlSession清空缓存User user2 = userDao.findById(45);System.out.println(user2);System.out.println(user1 == user2);session.close();}

清空缓存的操作很多,可以都试试。测试结果:

 二级缓存  
  再看一下Mybatis二级缓存是如何使用的,第一步让Mybatis框架支持二级缓存(在Mybatis的主配置文件中配置),第二步让当前的映射文件支持二级缓存(在Dao.xml映射文件中配置),第三步让当前的方法支持二级缓存(在标签中配置)。根据这个步骤将上面的查询用户的接口通过配置改造为可以支持二级缓存的方法。
1.配置Mybatis框架支持二级缓存

<setting name="cacheEnabled" value="true"/>

2.配置UserDao.xml支持二级缓存

 <cache/>

3.配置查询的方法支持二级缓存

<select id="findById" resultType="com.example.domain.User" parameterType="INT" useCache="true">SELECT * FROM  USER  WHERE ID = #{ID}
</select>

4.测试

@Testpublic void findByIdTest(){//第一次查询 并更新二级缓存SqlSession session1 = factory.openSession();UserDao userDao1 = session1.getMapper(UserDao.class);User user1 = userDao1.findById(45);System.out.println(user1);session1.commit(); //commit()方法提交二级缓存 同时清空一级缓存session1.close();////        user1.setUsername("更新用户");
//        user1.setAddress("更新地址");
//        userDao.updateUser(user1);//通过更新SqlSession清空缓存//第二次查找命中二级缓存SqlSession session2 = factory.openSession();UserDao userDao2 = session2.getMapper(UserDao.class);User user2 = userDao2.findById(45);session2.commit(); //commit()方法提交二级缓存 同时清空一级缓存session2.close();//System.out.println(user2);System.out.println(user1 == user2);}

测试结果:

总结:mybatis的的一级缓存是SqlSession级别的缓存,一级缓存缓存的是对象,当SqlSession提交、关闭以及其他的更新数据库的操作发生后,一级缓存就会清空。二级缓存是SqlSessionFactory级别的缓存,同一个SqlSessionFactory产生的SqlSession都共享一个二级缓存,二级缓存中存储的是数据,当命中二级缓存时,通过存储的数据构造对象返回。查询数据的时候,查询的流程是二级缓存>一级缓存>数据库。

Mybatis的一级缓存和二级缓存机制原理和区别相关推荐

  1. Mybatis缓存机制(一级缓存、二级缓存、三级缓存)

    一.含义: 缓存就是内存中的数据,常常来自对数据库查询结果的保存. 使用缓存,我们可以避免频繁与数据库进行交互,从而提高响应速度. Mybatis的缓存分为一级缓存.二级缓存.三级缓存. 一级缓存: ...

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

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

  3. 浅谈Mybatis的一级缓存和二级缓存

    MyBatis的缓存机制 缓存的引入 当我们大量执行重复的查询SQL语句的时候,会频繁的和数据库进行通信,会增加查询时间等影响用户体验的问题,可以通过缓存,以降低网络流量,使网站加载速度更快. MyB ...

  4. Mybatis源码分析之(七)Mybatis一级缓存和二级缓存的实现

    文章目录 一级缓存 二级缓存 总结 对于一名程序员,缓存真的很重要,而且缓存真的是老生常谈的一个话题拉.因为它在我们的开发过程中真的是无处不在.今天LZ带大家来看一下.Mybatis是怎么实现一级缓存 ...

  5. 框架源码专题:Mybatis的一级缓存、二级缓存是什么?有什么作用?

    文章目录 1. Mybatis中缓存的作用 2. 一级缓存 3. 二级缓存 4. 一级缓存和二级缓存的区别 5. 通过代码观察Mybatis缓存工作的全过程 1. Mybatis中缓存的作用 首先缓存 ...

  6. Mybatis的一级缓存和二级缓存详解

    注:本笔记是根据尚硅谷的MyBatis视频记录的 对于任何一个持久层框架,都有缓存机制:缓存在电脑中有一块真实的存储空间(https://baike.baidu.com/item/%E7%BC%93% ...

  7. mybatis之一级缓存和二级缓存

    缓存: 查询需要连接数据库,非常的耗费资源,将一次查询的结果,暂存在一个可以直接取到的地方,我们将其称之为缓存,当我们需要再次查询相同的数据时,直接走缓存这个过程,就不用走数据库了 缓存的概念: 存在 ...

  8. mybatis一级缓存和二级缓存使用详解

    文章目录 一.概念说明 1.一级缓存 2.二级缓存 3.比较 二.mybatis缓存的生命周期 三.一级缓存的使用 四.二级缓存的使用 五.自定义二级缓存 六.mybatis缓存.spring缓存和r ...

  9. Mybatis 一级缓存和二级缓存的使用

    目录 Mybatis缓存 一级缓存 二级缓存 缓存原理 Mybatis缓存 官方文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache My ...

最新文章

  1. oracle表增加自增主键,Oracle中给已存在的表增加自增主键
  2. oracle云产品是什么意思,Oracle云端产品线也要AI化,ERP云等4大主力云产品先升级...
  3. PAT甲级1101 Quick Sort:[C++题解]DP、快速排序划分个数、快排
  4. Java的List遍历
  5. JAVASCRIPT C# 相互访问
  6. Jira更换mysql数据库_JIRA6.0更换数据库到MYSQL
  7. 自动加密企业关键业务数据 赛门铁克推出全新信息保护解决方案
  8. docker学习(7) docker-compose使用示例
  9. 事业编,突然接到换岗通知,作为个人能怎么办?能拒绝换岗吗?拒绝的后果是什么?
  10. html+css的响应式个人简历
  11. 自媒体全套教程+全套工具(带教程)+原创实操教程
  12. 给自定义Dialog加入保留对话框值的功能
  13. 我知道苏宁会玩,但没想到它能把“千人千面”玩到了极致
  14. 解决线上问题-定位CPU占用过高
  15. 感悟 | 电影《你的名字》
  16. hibernate进行sum查询
  17. 从理念到大型实践,揭开腾讯零信任iOA安全方案的“落地密码”
  18. python与seo应用_Python在我SEO工作中的应用一 - 数据采集
  19. Linux运行python报错:Could not connect to any X display.
  20. wscript.shell用法

热门文章

  1. 数据可视化之使用Seaborn画热力图
  2. 区块链赋能律所非诉业务研究报告 | TokenInsight金杜律师事务所
  3. 易福门信号模块AL2341的安装
  4. Show, Attend and Tell: Neural Image Caption Generation with Visual Attention
  5. 3D U-Net: Learning Dense Volumetric Segmentation from Sparse Annotation
  6. 新手快速提升战力攻略-《无间狱》
  7. 最新检讨书生成工具小程序源码+支持流量主
  8. Linux上传文件时文件名自动加引号问题
  9. HyperLeger Fabric开发(十)——资产交易平台实战
  10. 人教社免费公布全学段教材电子版(附地址)