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()
可以看到命中缓存了。