题外话:
一级缓存只有在开启了数据库事物【@EnableTransactionManagement】并且处于一个被事物标注的方法下【直接或间接】才会生效。
在springboot下的配置
MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选:
A.session
在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中获取。
mybatis:
configuration:
cache-enabled: false #禁用二级缓存
local-cache-scope: session #一级缓存指定为session级别
B.statement
每次查询结束都会清掉一级缓存,实际效果就是禁用了一级缓存;
mybatis:
configuration:
cache-enabled: false #禁用二级缓存
local-cache-scope: statement #一级缓存指定为statement级别
二、不同设置方式在数据库事物中的表现
@Transactional(propagation = Propagation.REQUIRED)
public List<Users> getUsers() {
List<Users> usersList = usersMapper.selectByExample(new UsersExample()); #1
usersList = usersMapper.selectByExample(new UsersExample()); #2
return usersList;
}
A.一级缓存级别设置为session
在代码中1处,通过日志观察,打印出sql语句,未走缓存【此时缓存数据还不存在】;
在执行2处语句之前,通过数据库工具修改数据库记录并提交,继续执行程序后,通过日志观察,未打印出sql语句,获取的数据未体现出通过工具修改数据的变化,说明使用的是缓存中的数据;
B.一级缓存级别设置为statement
在代码中1处,通过日志观察,打印出sql语句,未走缓存【此时缓存数据还不存在】;
在执行2处语句之前,通过数据库工具修改数据库记录并提交,继续执行程序后,通过日志观察,打印出sql语句,且获取的数据也体现出通过工具修改数据的变化,说明未使用缓存中的数据;
结论:通过将一级缓存级别设置为statement,可以达到禁用一级缓存的效果。
@Transactional(propagation = Propagation.REQUIRED)
public List<Users> getUsers() {
List<Users> usersList = usersMapper.selectByExample(new UsersExample()); #1
usersList = usersServer.getUsersList();
return usersList;
}
#下面的代码属于usersServer
@Transactional(propagation = Propagation.NESTED) #3
public List<Users> getUsersList() {
return usersMapper.selectByExample(new UsersExample()); #2
}
观察到的结果与上面的一致。
结论:同上,同时证明了嵌套事物NESTED本质上与上层事物处于一个相同的事物中。
将代码3处事物配置调整成REQUIRES_NEW,重做之前的实验;
观察到的结果:在一级缓存级别为session与statement时,现象一致,带执行代码2处,均打印SQL语句,并且体现出了手动修改数据库记录的效果;
结论:REQUIRES_NEW确实重新起了一个新的事物,与上层事物没有关系。
终极结论
:
1.将mybatis一级缓存级别设置为statement可以事实上达到禁用一级缓存的效果;
2.启用mybatis一级缓存,将级别设置为session【或不做任何设置,mybaits默认就是这个级别】
二级缓存的设置也很简单,只需在Mapper.xml文件中加上cache标签即可
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.mapper.GoodsMapper">
<!--缓存标签-->
<cache></cache>
<resultMap id="BaseResultMap" type="com.example.demo.domain.entity.Goods">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="goods_name" jdbcType="VARCHAR" property="goodsName" />
<result column="number" jdbcType="INTEGER" property="number" />
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap>
<!--省略代码-->
总结:慎用一级缓存、二级缓存,最好关闭它们
————————————————
版权声明:本文为CSDN博主「NongYeting」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/NongYeting/article/details/106408985
原文链接:https://blog.csdn.net/gzmyh/article/details/133962866
原文链接:https://blog.csdn.net/a1036645146/article/details/106811411