作者:全me村的希望

https://www.cnblogs.com/hopeofthevillage/p/11427438.html

程序中为什么使用缓存?
  先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。对于我们编程来说,所谓的缓存,就是将程序
或系统经常要调用的对象(临时数据)存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统的开销,提高效率。
  对缓存有了一定的了解以后就知道了使用缓存是为了减少和数据库的交互次数,提高执行效率。那么下一个问题来了。什么样的数据能使用缓存,什么样的数据不能使用?
  这是我们使用缓存必须要明确的事情,实际上适用于缓存的数据:经常查询并且不经常改变的,并且的数据的正确与否对最终结果影响不大的、不适用于缓存的数据:经常改变的数据,数据的正确与否对最终
结果影响很大的。
  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     */    ListfindAll();    /**     * 根据Id查询用户     *     * @return     */    User findById(Integer id);    /**     * 更新用户     * @param user     */    void updateUser(User user);}

  3.UserDao.xml映射文件

namespace=    <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>    "updateUser" parameterType=        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}    

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

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

@Test    public 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进行清除缓存的操作,即清楚一级缓存,然后再次进行测试。

@Test    public 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框架支持二级缓存

"cacheEnabled" value="true"/>

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

 

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

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

  4.测试

@Test    public 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. 计算机一级证二级证是什么样的,计算机一级证和二级证有什么区别?

    一.考核技能不同 1.计算机一级:考核微型计算机基础知识和使用办公软件及因特网(Internet)的基本技能. 2.计算机二级:考核计算机基础知识和使用一种高级计算机语言编写程序以及上机调试的基本技能 ...

  2. 多级缓存架构还没听过?分布式多级缓存架构知识大瓶装,25 张图打包拎走

    一谈缓存,内心顿时豁然开朗.迫于key-value的形式,总感觉轻风扶面,杨柳依依,一切都尽在我掌握之中.犹如那一眼相中佳人的冲动,脑子里尽是佳人的容颜. 那缓存如果站在网站架构的角度,你知道它的设计 ...

  3. 什么是缓存?Mybaits一级缓存和二级缓存分别是什么,区别是什么?缓存和缓冲区的区别是什么?

    目录 一.什么是缓存 二.缓存的好处及缺点 三. 存(cache)与缓冲(buffer)的主要区别 四.Mybaits中缓存分为什么? 1.一级缓存 1.2一级缓存失效 2.二级缓存(不建议使用) 3 ...

  4. hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存

    hibernate二级缓存(三) 自定义实现一个简单的hibernate二级缓存 前面我们已经提及过hibernate内部为二级缓存的扩展做了很多的实现.我们只需要实现RegionFactoryTem ...

  5. 别盲从了,spring 解决循环依赖真的一定需要三级缓存吗?demo结合源码讲解三级缓存的真正目的,一级缓存singletonFactories的真正作用,看到文章最后让面试官眼前一亮

    背景 本篇是我上一篇<3分钟秒懂,最简单通俗易懂的spring bean 生命周期介绍与源码分析,附上demo完整源码>姊妹篇 spring 三级缓存问题是面试中的热点问题,大部分回答者会 ...

  6. 微型计算机中主板上的主桥,什么是微型计算机一级维修与二级维修如何对主板进行二级维修...

    什么是微型计算机一级维修与二级维修如何对主板进行二级维修 一级维修 一级维修,也叫板级维修.其维修对象是电脑中某一设备或某一部件,如主板.电源.显示器等,而且还包括电脑软件的设置.在这一级别,其维修方 ...

  7. 缓存系列之一:buffer、cache与浏览器缓存

    缓存系列之一:buffer.cache与浏览器缓存 一:缓存是为了调节速度不一致的两个或多个不同的物质的速度,在中间对速度较快的一方起到一个加速访问速度较慢的一方的作用,比如CPU的一级.二级缓存是保 ...

  8. apache缓存清理_深挖 Mybatis 源码:缓存模块

    作者:AmyliaY 出自:Doocs开源社区 原文:my.oschina.net/doocs/blog/4549852 MyBatis 中的缓存分为一级缓存.二级缓存,但在本质上是相同的,它们使用的 ...

  9. java ssm框架 缓存_SSM框架之MyBatis3专题4:查询缓存

    查询缓存的使用,主要是为了提高查询访问速度.将用户对同一数据的重复查询过程简化,不再每次均从数据库中查询获取结果数据,从而提高访问速度. MyBatis的查询缓存机制,根据缓存区的作用域(声明周期)可 ...

最新文章

  1. 实战:使用 Mask-RCNN 的停车位检测
  2. Oracle微服务框架 Helidon尝鲜(一)!~
  3. tfs 点获取最新,如果检查到大量冲突
  4. 通过串口输入控制指令控制图像在VGA显示器中的显示位置
  5. expect脚本的简单应用
  6. SMS中关于xp的sp3补丁的分发
  7. linux安装mysql 5.7_linux安装mysql5.7.24
  8. 5分钟实战QQ机器人教程(保姆级)
  9. QT 播放器之VideoWidget
  10. 大数据最佳实践-spark
  11. 深度残差网络+自适应参数化ReLU激活函数(调参记录2)
  12. 进程proc文件介绍
  13. C++:实现量化CPI债券交换测试实例
  14. 利用$randon和seed可以在测试脚本里面产生测试所需的赋值
  15. iOS KVC和KVO
  16. 计算机网页设计实习报告怎么写,网页设计实习报告.docx
  17. 【构成L2笔记:双主角 概括浅谈】
  18. 对话汇医慧影联合创始人郭娜:人工智能是分级诊疗的必然抓手
  19. mysql 幻读的隔离_MySQL的RR隔离级别与幻读问题
  20. html导航凹凸效果,纯CSS实现底部弧度效果(凹凸圆弧)

热门文章

  1. 2017.3.12 lzy 测试
  2. 【英语学习】【English L06】U03 House L5 Renting a House
  3. Android自定义View构造函数详解
  4. 求矩阵全部特征值和特征向量的QR方法
  5. 计算机网络学习笔记:第二章
  6. 一致性哈希算法 应用场景
  7. 如何修改select默认option数量多余显示滚动条查看_Chameleon for Mac(mac界面颜色修改工具)...
  8. 实时音频编程(二):实践与技巧
  9. socket 网络编程
  10. Linux下最快速共享目录的方法