程序中为什么使用缓存?
  先了解一下缓存的概念:原始意义是指访问速度比一般随机存取存储器快的一种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
*/
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)  命中一级缓存的情况
    测试代码:

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

<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.测试

@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. [原创]关于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. c语言进阶11-算法设计思想

    一.  算法设计的要求: 为什么要学算法? /* 输出Hello word! */ #include "stdio.h" void main() { printf("He ...

  2. java练习---13

    public class Y { public static void main(String[] args) { // TODO Auto-generated method stub new Y() ...

  3. [ PyQt入门教程 ] Qt Designer工具的使用

    Qt Designer是PyQt程序UI界面的实现工具,Qt Designer工具使用简单,可以通过拖拽和点击完成复杂界面设计,并且设计完成的.ui程序可以转换成.py文件供python程序调用.本文 ...

  4. Linux基础之特殊权限

    22.5)特殊权限 22.5.1)SetUID(简称suid)(数字权限是4000) 命令功能: 临时使用命令的属主权限执行该命令.即如果文件有suid权限时,那么普通用户去执行该文件时,会以该文件的 ...

  5. linuk下proftpd安装

    Linux下Proftpd安装与配置 1.下载 下载地址:ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.6rc1.tar.gz 文件下载到/soft ...

  6. SpringBoot Kafka 整合使用

    前提 假设你了解过 SpringBoot 和 Kafka. 1.SpringBoot 如果对 SpringBoot 不了解的话,建议去看看 DD 大佬 和 纯洁的微笑 的系列博客. 2.Kafka K ...

  7. 大型系列课程之-七夕告白之旅vbs篇

    也许,世间所有的美好的东西,都是需要仪式感的,遇到了一年一度的七夕节,怎么过这个节日,成了很多心中有爱的人关注的事情,七夕不浪漫,人间不值得,七夕,发源于中国,这个美好的节日,来自动人的神话故事传说牛 ...

  8. 算法与数据结构基础 - 位运算(Bit Manipulation)

    位运算基础 说到与(&).或(|).非(~).异或(^).位移等位运算,就得说到位运算的各种奇淫巧技,下面分运算符说明. 1. 与(&) 计算式 a&b,a.b各位中同为 1 ...

  9. 关于Oracle本地连接出现与监听有关的问题的解决方法探讨

    关于Oracle本地连接出现与监听有关的问题的解决方法探讨 监听的作用: 用于应用桌面即用户与数据库服务器建立连接的媒介,客户端发送连接请求,监听识别请求并建立客户端与服务器的连接后,监听的使命并完成 ...

  10. java中的各种锁详细介绍

    转自:https://blog.csdn.net/axiaoboge/article/details/84335452 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高 ...