title
1. Introduction to caching
Mybatis level cache is a SqlSession same scope, perform the same sql statement twice in the same sqlSession, the first complete implementation of
complete database queries will be written into the data cache (memory), and the second will be from the cache The data obtained from it will no longer be queried from the database, thereby improving
query efficiency. When a sqlSession ends, the first level cache in the sqlSession will no longer exist. Mybatis turns on the first level cache by default.
Mybatis second-level cache is shared by multiple SqlSessions, and its scope is the same namespace of the mapper. Different sqlSessions execute
the SQL statement under the same namespace twice and pass the same parameters to the SQL, that is, the same SQL statement is finally executed. After one execution
, the data queried in the database will be written to the cache (memory), and the data will be retrieved from the cache the second time, and the query will no longer be queried from the database, thereby improving query efficiency
. Mybatis does not enable the second-level cache by default. You need to configure the second-level cache in the setting global parameters.
If the second-level cache is not available, look for it from the first-level cache. If the first-level cache is not available, query from the database.
2. Level 1 cache, enabled by default, session level
Clearing the first level cache:
1、关于一级缓存的清空
一级缓存区域是根据SqlSession为单位划分的。
每次查询会先从缓存区域找,
如果找不到从数据库查询,查询
到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,
Key为hashCode+sqlId+sql语句。value为从查
询出来映射生成的Java对象。
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
Level 1 cache test:
// 一级缓存默认开启,二级缓存的开启需要配置
// 一级缓存的作用域:当前session
@Test
public void test1() {
StuInfoMapper stuMapper = sqlSession.getMapper(StuInfoMapper.class);
StuInfo stu = stuMapper.getStuInfoById(1);
System.out.println(stu);
// 这里是读取的缓存里面的stu
StuInfo stu1 = stuMapper.getStuInfoById(1);
System.out.println(stu1);
}
Query only once
Dirty read problem
Simply put: based on the caching mechanism in mybatis, the result of the query is the result in the cache, and the data is not updated immediately.
// 缓存带来的脏读问题
// 这里不开启二级缓存
@Test
public void test2() {
// 第一个session
SqlSession sqlSession1 = sqlSessionFactory.openSession();
StuInfoMapper stuInfoMapper1 = sqlSession1.getMapper(StuInfoMapper.class);
StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);
System.out.println(stu1);
// 第二个session
SqlSession sqlSession2 = sqlSessionFactory.openSession();
StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);
StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);
System.out.println(stu2);
// 实现commit 修改操作 清空session1, 重新查询
stuInfoMapper1.updateStuInfoById(new StuInfo(1, "jack-->小李子",
null, null, null));
sqlSession1.commit();
System.out.println("=============== after update... ================");
stu1 = stuInfoMapper1.getStuInfoById(1);
System.out.println("commit session1 重新查询.. " + stu1);
stu2 = stuInfoMapper2.getStuInfoById(1);
System.out.println("一级缓存中的stu2, 脏读... " + stu2);
}
3. The second level cache, the namespace level of the mapper
Enable caching
The current mapper enables secondary cache
test:
// 二级缓存在所有session之间共享。
@Test
public void test1() {
// session1
StuInfoMapper stuInfoMapper1 = sqlSession.getMapper(StuInfoMapper.class);
StuInfo stu1 = stuInfoMapper1.getStuInfoById(1);
// session1 关闭, 缓存到二级缓存中
sqlSession.close();
System.out.println(stu1);
// 先读二级缓存,不会查询数据库
SqlSession sqlSession2 = sqlSessionFactory.openSession();
StuInfoMapper stuInfoMapper2 = sqlSession2.getMapper(StuInfoMapper.class);
StuInfo stu2 = stuInfoMapper2.getStuInfoById(1);
System.out.println(stu2);
}