mybatis的缓存
一级缓存
特点:
①默认开启
②作用域是SqlSession级别(SqlSession对象中的一个HashMap)
③一级缓存直接缓存对象
④一级缓存基于BaseExecutor实现,直接找PerpetualCache查询map中的数据
执行流程:userMapper.select(参数) ---- DefaultSqlSession.selectList() ----- BaseExecutor.query()查询PerpetualCache中的Map是否有数据,有数据直接返回,没有数据查询数据库,将查询结果存放到一级缓存
@Test
public void findByCustomerId() throws IOException {
//1.加载核心配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2. 创建SqlSessionFactory(基于配置文件信息)
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.构建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.基于sqlSession获取指定Mapper的代理对象
CustomerMapper customerMapper = sqlSession.getMapper(CustomerMapper.class);
Customer customer = customerMapper.findByCustomerId(2);
Customer customer2 = customerMapper.findByCustomerId(2);
System.out.println(customer.toString());
for (LinkMan linkMan : customer.getLinkManSet()) {
System.out.println(linkMan.toString());
}
}
二级缓存
二级缓存特点:
- 二级缓存有三开关,全局开关默认开启,映射文件开关默认关闭,select语句开关默认开启
- 二级缓存的作用域是SqlSessionFactory级别。
- 二级缓存存储对象序列化的byte[]。
- 二级缓存基于CachingExecutor实现,二级缓存会结果一系列的Cache链(Synchronized,Logging,Serialized,Lru),最终找到PerpetualCache中的Map集合
- 二级缓存优先级高于一级缓存……
执行流程:userMapper.select(参数) ---- DefaultSqlSession.selectList() ----- CachingExecutor.query(),经历一套Cache链,然后查询PerpetualCache中的Map是否有数据,有数据直接返回,没有数据查询一级缓存,如果一级缓存没有,查询数据库,将查询结果存放到一级缓存,在commit提交事务后,将数据存储到二级缓存
@Test
public void twoLevelCache() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession1 = factory.openSession();
SqlSession sqlSession2 = factory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.findById(1);
sqlSession1.commit();
sqlSession1.close();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = userMapper2.findById(1);
sqlSession2.commit();
sqlSession2.close();
System.out.println(user1 == user2);
}