Mybatis 事务管理和缓存机制
一级缓存--SqlSession级别
数据库表tb_user
User

package com.example.demo.domain; public class User { private Integer id; private String name; private String sex; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
UserMapper

package com.example.demo.mapper; import com.example.demo.domain.User; import java.util.List; public interface UserMapper { User selectUserById(Integer id); List<User> selectAllUser(); void deleteUserById(Integer id); }
UserMapper.xml

<?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.mapper.UserMapper"> <select id="selectUserById" parameterType="int" resultType="com.example.demo.domain.User"> SELECT * FROM tb_user WHERE id=#{id} </select> <select id="selectAllUser" resultType="com.example.demo.domain.User"> SELECT * FROM tb_user </select> <delete id="deleteUserById" parameterType="int"> DELETE FROM tb_user WHERE id=#{id} </delete> </mapper>
FKSqlSessionFactory

package com.example.demo.factory; 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 java.io.IOException; import java.io.InputStream; public class FKSqlSessionFactory { private static SqlSessionFactory sqlSessionFactory=null; static { try { InputStream inputStream= Resources.getResourceAsStream("mybatis-config.xml"); sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } }
TestOneLevelCache

package com.example.demo.test; import com.example.demo.domain.User; import com.example.demo.factory.FKSqlSessionFactory; import com.example.demo.mapper.UserMapper; import org.apache.ibatis.session.SqlSession; public class TestOneLevelCache { public static void main(String[] args){ TestOneLevelCache testOneLevelCache=new TestOneLevelCache(); testOneLevelCache.testCache1(); } public void testCache1(){ SqlSession session= FKSqlSessionFactory.getSqlSession(); UserMapper mapper=session.getMapper(UserMapper.class); User user=mapper.selectUserById(1); System.out.println(user); User user1=mapper.selectUserById(1); System.out.println(user1); session.close(); } public void testCache2() { SqlSession session = FKSqlSessionFactory.getSqlSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user); mapper.deleteUserById(4); User user1=mapper.selectUserById(1); System.out.println(user1); session.close(); } }
运行testcache1
可以看到只查询了一次,返回的是同一个对象。
运行testcache2
当SqlSession执行过DML操作(insert,update,delete)并提交到数据库后,Mybatis会清空一级缓存。
新加testCache3方法

public void testCache3(){ SqlSession session = FKSqlSessionFactory.getSqlSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user); session.close(); session = FKSqlSessionFactory.getSqlSession(); mapper = session.getMapper(UserMapper.class); user = mapper.selectUserById(1); System.out.println(user); session.close(); }
运行
此时可以看到查询了两次。
二级缓存--mapper级别
MyBatis默认开启一级缓存,开启二级缓存需要在settings中配置
<settings> <setting name="cacheEnabled" value="true"></setting> </settings>
在UserMapper.xml中添加配置
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"></cache>
这里添加了一个LRU(最近最少使用策略)缓存,每隔60秒刷新,最大存储512个对象,且返回对象为只读。
TestTwoLevelCache

package com.example.demo.test; import com.example.demo.domain.User; import com.example.demo.factory.FKSqlSessionFactory; import com.example.demo.mapper.UserMapper; import org.apache.ibatis.session.SqlSession; public class TestTwoLevelCache { public static void main(String[] args){ TestTwoLevelCache testTwoLevelCache=new TestTwoLevelCache(); // testTwoLevelCache.testCache1(); testTwoLevelCache.testCache2(); } public void testCache1(){ SqlSession session = FKSqlSessionFactory.getSqlSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user); mapper.deleteUserById(4); User user1=mapper.selectUserById(1); System.out.println(user1); session.close(); } public void testCache2(){ SqlSession session = FKSqlSessionFactory.getSqlSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user); session.close(); session = FKSqlSessionFactory.getSqlSession(); mapper = session.getMapper(UserMapper.class); user = mapper.selectUserById(1); System.out.println(user); session.close(); } }
运行testCache2()
可以看到命中缓存了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!