一级缓存和二级缓存
/**
* 1.一级缓存:
* 1.1 一级缓存和线程(session:会话)有关,也就是 不同的线程进行访问同一 sql,他们的一级缓存是不共享的
* 1.2 mybatis 一级缓存失效原因,
* 由于 mybatis 整合到 spring 中
* mybatis 的 session 交给 spring 管理
* spring 在执行 sql 时,会产生一个代理,由代理来执行
* 代理每次执行 sql 后,会将 session 关闭,这就导致一级缓存失效
* spring 在执行 sql 时,是使用代理执行的
*
*
* 2.二级缓存:
* 2.1 开启,在 Mapper 上加注解: {@link org.apache.ibatis.annotations.CacheNamespace}
* 2.2 <存在的坑> 命名空间:
* 如果我们在命名空间 userMapper1 中查询到一些数据,开启二级缓存后,会将这些数据缓存到命名空间内
* 但,如果我们在命名空间 userMapper2 中修改了一些数据,它会使 userMapper2 的缓存失效
* 但,如果我们继续在 userMapper1 查询相同的信息的时候,查询到的信息都是没有修改的数据(脏数据)
* --- 也就是说,在不同命名空间操作之后,可能会产生脏数据
*
* 3. 一级缓存和二级缓存是有些鸡肋的功能,因此,现在通常使用 redis 作为缓存使用
*
*/
mybatis 执行流程和 mybatis-spring 执行流程
/**
* 分为:1.mybatis 执行流程
* 2.mybatis 整合到 spring 的执行流程
*
* 1.打开 SqlSession 后,使用其实现类 DefaultSqlSession 直接执行查询(Executor.query())
*
* 2.打开 SqlSession 后,SqlSession 会产生:SqlSessionTemplate,
* SqlSessionTemplate 包含 sqlSession 和一个代理对象 sqlSessionProxy,然后使用 sqlSessionProxy 执行查询(proxy.query())
* 每次查询后,就会执行 sqlSession.close(),导致一级缓存失效
*
* -- 也就是说,如果整合到 spring,就会使用 SqlSessionTemplate 对 DefaultSqlSession 进行代理增强,
*
*
*
* -- 为什么 spring 要在每次 sql 执行后关闭 session 呢?
* 因为 spring 没有把代理的对象纳入到 spring 容器
* 我们也无法获取到这个 session,因此,如果 spring 不关闭session,我们又获取不到
* 那么 session 就没有办法关闭了
*
* -- 而直接使用 mybatis (不整合到 spring) 可以手动关闭
* 因为我们可以直接获取到 session,想在什么时候关闭就在什么时候关闭
* (因为 spring 会将 session 转成代理,我们无法获取,而直接使用 mybatis 不是用代理,可以直接获取)
*
*
*
*
*/