同一个 SqlSession 对象, 在参数和 SQL 完全一样的情况先, 只执行一次 SQL 语句(如果缓存没有过期)
也就是只有在参数和 SQL 完全一样的情况下, 才会有这种情况。
1.1 同一个 SqlSession
@Test public void oneSqlSession() { SqlSession sqlSession = null; try { sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); List<Student> students = studentMapper.selectAll(); for (int i = 0; i < students.size(); i++) { System.out.println(students.get(i)); } System.out.println("=============开始同一个 Sqlsession 的第二次查询============"); List<Student> stus = studentMapper.selectAll(); Assert.assertEquals(students, stus); for (int i = 0; i < stus.size(); i++) { System.out.println("stus:" + stus.get(i)); } } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) { sqlSession.close(); } } }
在以上的代码中, 进行了两次查询, 使用相同的 SqlSession, 结果如下
 25px 0px no-repeat; border: 2px solid rgb(239, 239, 239); min-height: 35px; line-height: 1.6em; color: rgb(51, 51, 51);)
flushCache="true"
修改后的配置文件如下:
<select id="selectByPrimaryKey" flushCache="true" parameterType="java.lang.Integer" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from student where student_id=#{id, jdbcType=INTEGER} </select>
结果如下:

第一次, 第二次都发送了 SQL 语句, 同时, 断言两个对象相同出错。
1.4 总结
-
在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;
-
不同的 SqlSession 之间的缓存是相互隔离的;
-
用一个 SqlSession, 可以通过配置使得在查询前清空缓存;
-
任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。
2 二级缓存
二级缓存存在于 SqlSessionFactory 生命周期中。
2.1 配置二级缓存
2.1.1 全局开关
在 mybatis 中, 二级缓存有全局开关和分开关, 全局开关, 在 mybatis-config.xml 中如下配置:
<settings> <setting name="cacheEnabled" value="true"/> </settings>
默认是为 true, 即默认开启总开关。
2.1.2 分开关
分开关就是说在 *Mapper.xml中开启或关闭二级缓存, 默认是不开启的。
2.1.3 entity 实现序列化接口
关键字: