初识mybatis中的缓存
mybatis中的缓存
一级缓存
mybati的一级缓存作用域为session,当执行opensession()后,结果和sql会被存入缓存中,如果下次执行的sql(参数 语句)相同就直接从缓存当中拿取,而不再执行sql从数据库查询
mybatis中一级缓存是默认开启的,并且是一直开启的且无法关闭
关闭掉当前的session对象可以达到强制清除缓存的效果
案例演示:
新建一个基本的MyBatis项目
Uesr类:
public class User {
//account的实体封装属性
private String name;
private Integer id;
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", id=" + id +
", money=" + money +
'}';
}
private Float money;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Float getMoney() {
return money;
}
public void setMoney(Float money) {
this.money = money;
}
}
UserMapper类(暂时提供一个方法):
public interface UserMapper {
/**
* 根据id查询
*/
public User findAllById(Integer id);
}
TestMybatis测试类:
@Test
public void findAllById() throws IOException {
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.findAllById(11);
System.out.println(user);
}
注意这里的MybatisUtil类是单独的把session对象提取出来了
MybatisUtil类:
public class MybatisUtil {
public static SqlSession openSession() throws IOException {
InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
return session;
}
}
在测试类中测试一级缓存
不清除session
@Test
public void findAllById() throws IOException {
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
//第一次查询
User user = mapper.findAllById(11);
System.out.println(user);
//进行第二次查询
User user1 = mapper.findAllById(11);
System.out.println(user1);
}
可以发现两次查询只使用了一次sql语句,使用同一个查询到的结果
控制台输出:
//sql语句
DEBUG [main] - ==> Preparing: select * from account where id = ?
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <== Total: 1
User{name='ccc', id=11, money=1000.0}
User{name='ccc', id=11, money=1000.0}
强制清除掉session
@Test
public void findAllById() throws IOException {
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
//第一次查询
User user = mapper.findAllById(11);
System.out.println(user);
//清除缓存
session.clearCache();
System.out.println("清除缓存成功");
//进行第二次查询
User user1 = mapper.findAllById(11);
System.out.println(user1);
}
控制台日志打印两次查询使用了两个sql语句
//第一次查询使用的sql
DEBUG [main] - ==> Preparing: select * from account where id = ?
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <== Total: 1
User{name='ccc', id=11, money=1000.0}
清除缓存成功
//第二次查询使用的sql
DEBUG [main] - ==> Preparing: select * from account where id = ?
DEBUG [main] - ==> Parameters: 11(Integer)
DEBUG [main] - <== Total: 1
User{name='ccc', id=11, money=1000.0}
注意: 执行update、insert、delete的时候,会清空缓存;
当然这在逻辑中是绝对正确的,如果你在执行更新,添加 ,删除的时候还保存着上一次的数据和sql的话那么下一次就永远是上一次的结果,且只会是第一次的结果
在类中测试:
@Test
public void findAllById() throws IOException {
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper.findAllById(15));
User user = new User();
user.setMoney(20000F);
//执行update方法
mapper.updateUser(user);
//提交事务
session.commit();
//第二次查询
System.out.println(mapper.findAllById(15));
}
通过前面的案例我们知道执行的sql相同只会执行一次sql而现在的控制台日志打印执行了两次sql说明执行的update方法清除掉了缓存
控制台日志打印:
//第一次查询
DEBUG [main] - ==> Preparing: select * from account where id = ?
DEBUG [main] - ==> Parameters: 15(Integer)
DEBUG [main] - <== Total: 1
User{name='lk阿b', id=15, money=10000.0}
//执行update方法
DEBUG [main] - ==> Preparing: update account SET money=? where id=?
DEBUG [main] - ==> Parameters: 20000.0(Float), null
DEBUG [main] - <== Updates: 0
DEBUG [main] - Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1c93084c]
//第二次查询
DEBUG [main] - ==> Preparing: select * from account where id = ?
DEBUG [main] - ==> Parameters: 15(Integer)
DEBUG [main] - <== Total: 1
User{name='lk阿b', id=15, money=10000.0}
二级缓存
mybatis 的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中命中。
开启mybatis的二级缓存需要在mapper标签中添加标签以开启二级缓存
在UserMapper.xml配置文件中添加开启二级缓存的标签
<!-- 开启二级缓存 -->
<cache></cache>
在MybatisTest测试类中添加testCache()测试方法
@Test
public void testCache() throws IOException {
//第一次查询
SqlSession session = MybatisUtil.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper.findAllById(15));
//关闭session对话,相当于清除session的一级缓存
session.close();
//第二次
SqlSession session1 = MybatisUtil.openSession();
UserMapper mapper1 = session1.getMapper(UserMapper.class);
System.out.println(mapper1.findAllById(15));
}
运行testCache()方法会报java.io.NotSerializableException错误
原因是:二级缓存 必须要让缓存对象实现序列化接口;由于User类没有实现序列化接口,所以出现反序列异常;
那么我们让User类实现序列化接口Serializable就可以了;
public class User implements Serializable {
//序列化id
private static final long serialVersionUID = -7143822134269505369L;
关闭二级缓存可以在sqlMapConfig.xml中全局配置
<configuration>
<properties resource="jdbc.properties"/>
<settings>
<!-- 开启二级缓存全局总开关,这里关闭了在userMapper中开启也没用-->
<setting name="cacheEnabled" value="false"/>
</settings>
- overlayfs存储驱动的使用以及技术探究
- 分页解决方案 之 分页算法——Pager_SQL的详细使用方法和注意事项
- 利用虚拟硬盘(把内存当作硬盘)来提高数据库的效率(目前只针对SQL Server 2000)可以提高很多
- 分页解决方案 之 分页算法——Pager_SQL的思路和使用方法
- 让你的笔记本更快一点——我的笔记本的性能测试和虚拟硬盘(把内存当成硬盘)的使用感觉
- 分页解决方案 之 数据访问函数库——另类的思路、另类的写法,造就了不一样的发展道路。
- 分页解决方案 之 QuickPager的使用方法(在UserControl里面使用分页控件的方法)
- 分页解决方案 之 QuickPager的使用方法(URL分页、自动获取数据)
- 分页解决方案 之 QuickPager的使用方法(PostBack分页、自定义获取数据)
- QuickPager asp.net 分页控件、表单控件等自定义控件下载 和介绍 【2009.09.07更新】
- 分页解决方案 之 QuickPager的使用方法(PostBack分页、自动获取数据)
- 【自然框架】之鼠标点功能现(二):表单控件的“应用”—— 代码?只写需要的!
- 基于Docker环境中源码部署容器Nginx
- 使用Ansible playbooks快速构建etcd集群
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- MapReduce之自定义分区器Partitioner
- MySQL ORDER BY,GROUPBY 与各种JOIN
- (三) Mybatis动态SQL语句 - Titan的Mybatis系列学习笔记
- (二) 使用Mybatis完成CRUD操作 - Titan的Mybatis系列学习笔记
- 轻松使用纯css3打造有点意思的故障艺术(附React加强组件版)
- (一)Mybatis的入门 - Titan的Mybatis系列学习笔记
- Hadoop安装与环境配置入门
- Elasticsearch源码解析:环境搭建
- SpringBoot整合JWT认证机制实现接口鉴权
- [Java] Java多线程的探索 -获取新闻标题
- Java中对文件进行MD5加密
- [数据结构] 使用最小堆思想实现哈夫曼编解码
- [数据结构] 括号符的匹配
- [数据结构] 平衡二叉查找树 (AVL树)
- 写给前端的算法进阶指南,我是如何两个月零基础刷200题