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

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

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

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

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

 package top.bigking;

 import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import top.bigking.dao.DeptMapper;
import top.bigking.dao.UserMapper;
import top.bigking.pojo.Dept;
import top.bigking.pojo.User; import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class mybatisStudy_start {
public static void main(String[] args) throws Exception{
InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> deptList = deptMapper.query();
for(Dept dept : deptList){
System.out.println(dept);
}
System.out.println("-----------------------------------");
//insert(deptMapper);
//update(deptMapper);
findById(deptMapper); findById(deptMapper);
//delete(deptMapper);
//findByIdDname(deptMapper); // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// List<User> userList = userMapper.query();
// for(User user : userList)
// System.out.println(user);
sqlSession.close(); }
private static void insert(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("111");
int count = deptMapper.insert(dept);
System.out.println(count);
}
public static void update(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("上海");
int count = deptMapper.update(dept);
System.out.println(count);
}
public static void findById(DeptMapper deptMapper){
Dept dept = deptMapper.findById(11);
System.out.println(dept);
}
public static void delete(DeptMapper deptMapper){
int count = deptMapper.delete(11);
System.out.println(count);
}
public static void findByIdDname(DeptMapper deptMapper){
Map map = new HashMap();
map.put("deptNo", "11");
map.put("dname", "ABKing");
Dept dept = deptMapper.findByIdDname(map);
System.out.println(dept);
}
}

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

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

只打印出了一条SQL语句

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

 package top.bigking;

 import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import top.bigking.dao.DeptMapper;
import top.bigking.dao.UserMapper;
import top.bigking.pojo.Dept;
import top.bigking.pojo.User; import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class mybatisStudy_start {
public static void main(String[] args) throws Exception{
InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> deptList = deptMapper.query();
for(Dept dept : deptList){
System.out.println(dept);
}
System.out.println("-----------------------------------");
//insert(deptMapper);
//update(deptMapper);
findById(deptMapper);
sqlSession.clearCache();
findById(deptMapper);
//delete(deptMapper);
//findByIdDname(deptMapper); // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// List<User> userList = userMapper.query();
// for(User user : userList)
// System.out.println(user);
sqlSession.close(); }
private static void insert(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("111");
int count = deptMapper.insert(dept);
System.out.println(count);
}
public static void update(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("上海");
int count = deptMapper.update(dept);
System.out.println(count);
}
public static void findById(DeptMapper deptMapper){
Dept dept = deptMapper.findById(11);
System.out.println(dept);
}
public static void delete(DeptMapper deptMapper){
int count = deptMapper.delete(11);
System.out.println(count);
}
public static void findByIdDname(DeptMapper deptMapper){
Map map = new HashMap();
map.put("deptNo", "11");
map.put("dname", "ABKing");
Dept dept = deptMapper.findByIdDname(map);
System.out.println(dept);
}
}

此时查看控制台的日志

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

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

接下来证明二级缓存:

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

代码如下:

 package top.bigking;

 import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import top.bigking.dao.DeptMapper;
import top.bigking.dao.UserMapper;
import top.bigking.pojo.Dept;
import top.bigking.pojo.User; import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class mybatisStudy_start {
public static void main(String[] args) throws Exception{
InputStream in = Resources.getResourceAsStream("mybatisStudy-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//true 表示 自动提交
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
DeptMapper deptMapper1 = sqlSession1.getMapper(DeptMapper.class);
List<Dept> deptList = deptMapper.query();
for(Dept dept : deptList){
System.out.println(dept);
}
System.out.println("-----------------------------------");
//insert(deptMapper);
//update(deptMapper);
findById(deptMapper);
sqlSession.close();
//sqlSession.clearCache();
findById(deptMapper1);
sqlSession1.close();
//delete(deptMapper);
//findByIdDname(deptMapper); // UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// List<User> userList = userMapper.query();
// for(User user : userList)
// System.out.println(user);
//sqlSession.close(); }
private static void insert(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("111");
int count = deptMapper.insert(dept);
System.out.println(count);
}
public static void update(DeptMapper deptMapper){
Dept dept = new Dept();
dept.setDeptNo(11);
dept.setDname("ABKing");
dept.setLoc("上海");
int count = deptMapper.update(dept);
System.out.println(count);
}
public static void findById(DeptMapper deptMapper){
Dept dept = deptMapper.findById(11);
System.out.println(dept);
}
public static void delete(DeptMapper deptMapper){
int count = deptMapper.delete(11);
System.out.println(count);
}
public static void findByIdDname(DeptMapper deptMapper){
Map map = new HashMap();
map.put("deptNo", "11");
map.put("dname", "ABKing");
Dept dept = deptMapper.findByIdDname(map);
System.out.println(dept);
}
}

在DeptMapper.xml中

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

通过useCache可以使用二级缓存

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

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

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

查看控制台输出的日志:

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

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

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

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

表示不使用二级缓存

运行,查看控制台:

DEBUG [main] - ==>  Preparing: select deptNo, dname, loc from Dept where deptNo=?
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <== Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a9273a8]
DEBUG [main] - Returned connection 2056418216 to pool.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Checked out connection 2056418216 from pool.
DEBUG [main] - ==> Preparing: select deptNo, dname, loc from Dept where deptNo=?
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <== Total: 1
Dept{deptNo=11, dname='ABKing', loc='111'}
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. 【leetcode】Global and Local Inversions

    题目如下: We have some permutation A of [0, 1, ..., N - 1], where N is the length of A. The number of (g ...

  2. CF1263F

    题目描述 给出一个类似这样 的图,求删掉最多的黑边使得每个特殊点和至少一个节点1连通 保证上下两棵树都存在一种dfs序使得访问特殊点的顺序为1~n 题解 设f[i][j]表示上面的树最后一个特殊点为i ...

  3. java总结1

    栈,堆,方法区.main和局部变量在栈,new 对象 在堆, 类和常量在方法区除了8大基础数据类型,其他都为引用变量局部变量在函数内或方法上声明,没有默认值,定义必须赋值一旦提供构造方法,就不会有默认 ...

  4. BZOJ 4373: 算术天才⑨与等差数列 线段树

    Description 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能 ...

  5. MySQL_DQL操作

    DQL(Data Query Language)简单的来说就是数据的查询语言. 1.最简单的查询(显示表中的所有信息) 语法: select * from 表名; 2.普通查询 语法: select ...

  6. Linux6.6及以上版本配置oracle-ASM共享储存-UDEV-V1

    1,在该路劲下创建50-udev.rules文件,将要创建成ASM设备的裸设备添加进去,并指定OWNER 两个节点进行创建 [root@oraclea rules.d]# pwd/etc/udev/r ...

  7. Java equals 和 hashCode 的这几个问题可以说明白吗?

    前言 上一篇文章 如何妙用 Spring 数据绑定? ,灵魂追问 环节留下了一个有关 equals 和 hashcode 问题 .基础面试经常会碰到与之相关的问题,这不是一个复杂的问题,但很多朋友都苦 ...

  8. 一款基于jQuery的分页插件

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  9. Oracle JET mobile 入门使用

    Oracle JET 框架能开发 window, Android, ios 的 WebApp .主要使用 Codova 来进行开发. 简单使用 Oracle JET 开发 Android webapp ...

  10. 通过同步上下文方式更新winform中的控件信息

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...