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 * from users where id = #{id}
update users set username = #{username}, age = #{age} where id = #{id}
测试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为单元。
在映射文件中加入 即可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个对象