day115 - mybatis的缓存

发布时间 2023-07-06 12:11:39作者: 北海之上

mybatis的缓存

mybatis的一级缓存

一级缓存是sqlsession级别的,即通过同一个SQL session查询的数据会被缓存
再次使用同一个SQL session查询同一条数据会从缓存中获取

一级缓存的失效情况

使一级缓存失效的四种情况:
  1. 不同的SQL session对应不同的一级缓存
  2. 同一个SQL session对应的查询条件不同
  3. 同一个SQL session两次查询之间执行了任意一次增删改操作
  4. 同一个SQL session两次查询操作中间手动清空了缓存
      sqlSession.clearCache();

test

/**
 * 根据员工id查询员工信息
 * @param empId
 * @return
 */
Emp getEmpById(@Param("empId") Integer empId);
<!--  Emp getEmpById(@Param("empId") Integer empId);  -->
<select id="getEmpById" resultType="com.gu.mybatis.pojo.Emp">
    select * from t_emp where emp_id = #{empId}
    </select>
@Test
public void testGetEmpId(){
    SqlSession sqlSession = SqlSessionUtil.getSqlSession();
    CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
    Emp empById1 = mapper.getEmpById(1);
    System.out.println(empById1);
    sqlSession.clearCache();
    Emp empById2 = mapper.getEmpById(1);
    System.out.println(empById2);
}

 

mybatis的二级缓存

二级缓存是SQLsessionfactory级别的,通过同一个SQLsessionfactory所获取的SQL session对象查询的数据会被缓存
再通过同一个SQLsessionfactory所获取的SQL session查询相同的数据会从缓存中获取

二级缓存的开启条件

a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
b>在映射文件中设置标签<cache/>
c>二级缓存必须在SqlSession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口

二级缓存的失效条件

在两次查询之间执行了任意一次增删改操作
sqlSession.clearCache();只能清楚一级缓存,不会清除二级缓存。

test

@Test
public void testCache() throws IOException {
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
    SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
    CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
    Emp emp1 = mapper1.getEmpById(1);
    System.out.println(emp1);
    sqlSession1.close();
    CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
    Emp emp2 = mapper2.getEmpById(1);
    System.out.println(emp2);
​
}

 

mybatis缓存查询顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
如果二级缓存没有命中,再查询一级缓存
如果一级缓存也没有命中,则查询数据库
SqlSession关闭之后,一级缓存中的数据会写入二级缓存