缓存是值,本次查询过的数据,下一次如果查询到一样的,可以将它先缓存起来,这样mybatis不需要每次去查询。
注意: 一级缓存是默认开启
一级缓存是Sqlsession级别的,通过同一个Sqlsession查询的数据会被缓存。此后若查询相同的数据,则会从缓存中直接获取。
一级缓存失效的四个情况:
1. 不同的Sqlsession对应不同的一级缓存。
2. 同一个sqlsession但是查询条件不同。
3. 同一个sqlsession再次查询期间执行了一次增删改操作。
4. 同一个sqlsession查询手动清理了缓存。
目录
1. 接口
Emp getEmpByEid(@Param("eid") Integer eid);
2. mapper映射文件
<!-- Emp getEmpByEid(@Param("eid") Integer eid);-->
<select id="getEmpByEid" resultType="Emp">
select * from t_emp where eid=#{eid}
</select>
3. 测试类
@Test
public void testCache(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEid(1);
Emp emp2 = mapper.getEmpByEid(1);
System.out.println(emp1);
System.out.println(emp2);
}
测试结果,我们可以从log里看出,sql就调用了一次,那么第二次的输出是从mybatis的缓存里取的数值。
20:33:36:992 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Preparing: select * from t_emp where eid=?
20:33:37:277 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Parameters: 1(Integer)
20:33:37:369 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - <== Total: 1
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
4. 引申,如何不从缓存获取
修改测试类, 添加sqlSession类,用不同的sqlsession取获取mapper和调用方法。
public void testCache(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEid(1);
System.out.println(emp1);
SqlSession sqlSession1 = SqlSessionUtils.getSqlSession();
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp2 = mapper1.getEmpByEid(1);
System.out.println(emp2);
}
}
我们可以从Log看出,SQL执行了两次,并没有从缓存中自动获取。
20:37:59:312 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Preparing: select * from t_emp where eid=?
20:37:59:390 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Parameters: 1(Integer)
20:37:59:422 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - <== Total: 1
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
20:37:59:547 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Preparing: select * from t_emp where eid=?
20:37:59:547 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Parameters: 1(Integer)
20:37:59:547 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - <== Total: 1
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
5. 总结
一级缓存的范围是sqlsession.
6. 手动清除缓存
使用 sqlsession的 clearCache()方法清空缓存。
修改测试类如下:
public void testCache(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
Emp emp1 = mapper.getEmpByEid(1);
System.out.println(emp1);
sqlSession.clearCache();
Emp emp2 = mapper.getEmpByEid(1);
System.out.println(emp2);
}
10:09:35:130 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Preparing: select * from t_emp where eid=?
10:09:35:217 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Parameters: 1(Integer)
10:09:35:279 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - <== Total: 1
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
10:09:35:286 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Preparing: select * from t_emp where eid=?
10:09:35:286 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - ==> Parameters: 1(Integer)
10:09:35:286 [main] DEBUG org.apache.ibatis.logging.jdbc.BaseJdbcLogger 137 - <== Total: 1
Emp{eid=1, empName='张三', age=32, sex='男', email='123@qq.com', dept=null}
我们可以从LOG看出,sql执行了两次,手动清理缓存成功。