1.一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为session,当session被flush或close之后,该session中的所有Cache就将清空。
2.二级缓存与一级缓存机制相同,默认也采用PerpetualCache HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache。
3.对于缓存数据更新机制,当一个作用域(一级缓存session/二级缓存Namespace )进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear.
User.java 实体类
public class User { private int id; private String username; private int age; private String sex; //... }
<select id="getUser" parameterType="int" resultType="com.mybatis.test07.User"> select * from users where id = #{id} </select> <update id="updateUser" parameterType="com.mybatis.test07.User"> update users set username = #{username}, age = #{age} where id = #{id} </update>
测试
SqlSessionFactory factory = MybatisUtil.getFactory(); SqlSession session = factory.openSession(); String statement = "com.mybatis.test06.userMapper.getUser"; User user = session.selectOne(statement, 2); System.err.println(user); user = session.selectOne(statement, 2); System.err.println(user); session.close(); //默认情况下一级缓存已开启。两次查询同一个对象,只会进行一次select操作
SqlSessionFactory factory = MybatisUtil.getFactory(); SqlSession session = factory.openSession(true); String statement = "com.mybatis.test07.userMapper.getUser"; User user = session.selectOne(statement, 2); System.err.println(user); //进行update操作 user.setId(11); statement = "com.mybatis.test07.userMapper.updateUser"; System.err.println(user); session.update(statement, user); //重新发出查询 statement = "com.mybatis.test07.userMapper.getUser"; user = session.selectOne(statement, 2); System.err.println(user); session.close();
SqlSessionFactory factory = MybatisUtil.getFactory(); SqlSession session = factory.openSession(true); String statement = "com.mybatis.test07.userMapper.getUser"; User user = session.selectOne(statement, 2); System.err.println(user); SqlSession session1 = factory.openSession(true); user = session1.selectOne(statement, 2); System.err.println(user); session.close(); session1.close(); //两个不同的session对象
三种情况不能利用一级缓存:①执行了session.clearCache(); ②执行了CUD操作 ③不是同一个session对象
二级缓存以namespace为单元,即以映射文件为单元。Hibernate二级缓存以SessionFactory为单元。
在映射文件中加入 <cache/> 即可
SqlSessionFactory factory = MybatisUtil.getFactory(); SqlSession session = factory.openSession(); String statement = "com.mybatis.test07.userMapper.getUser"; User user = session.selectOne(statement, 2); System.err.println(user); //User(com.mybatis.test07.User@1a78071) [id=2, username=syd, age=34, sex=男] session.commit(); SqlSession session1 = factory.openSession(); user = session1.selectOne(statement, 2); System.err.println(user); //User(com.mybatis.test07.User@182ef6b) [id=2, username=syd, age=34, sex=男] session1.commit(); session.close(); session1.close();
两次不是同一个对象,但是第二次并没有从数据库中去查询。
1.映射语句文件中的所有select语句将会被缓存
2.映射语句文件中所有的insert update delete语句会刷新缓存
3.缓存会使用Least Recently Used (LRU 最近最少使用) 算法来收回
4.缓存会根据指定的时间间隔来刷新
5.缓存会存储1024个对象