1. 一级缓存:其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
2. 二级缓存与一级缓存其机制相同,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如第三方 Ehcache。
一、一级缓存
实体类city
public class City implements Serializable{ private static final long serialVersionUID = 1L; private int id; private String cityName; private String provinceId; //getters、setters }
CityMapper
<mapper namespace="com.area.dao.CityDao"> <select id="findByProvinceId" resultType="city"> select * from city where provinceId = #{pId} </select> </mapper>
测试;
@Test public void testById() { sqlSession = sqlSessionFactory.openSession(); CityDao cityDao = sqlSession.getMapper(CityDao.class); cityDao.findByProvinceId("p1"); cityDao.findByProvinceId("p1"); sqlSession.commit(); }
测试结果
[com.area.dao.CityDao.findByProvinceId] - ==> Preparing: select * from city where provinceId = ? [com.area.dao.CityDao.findByProvinceId] - ==> Parameters: p1(String) [com.area.dao.CityDao.findByProvinceId] - <== Total: 1
从sql中可以看出,只有一次查询数据库的过程,这种现象产生的原因就是mybatis的一级缓存,并且一级缓存是默认开启的。
二、二级缓存
未开启二级缓存
@Test public void test() { sqlSession = sqlSessionFactory.openSession(); CityDao cityDao = sqlSession.getMapper(CityDao.class); cityDao.findByProvinceId("p1"); sqlSession.commit(); sqlSession1 = sqlSessionFactory.openSession(); CityDao cityDao1 = sqlSession1.getMapper(CityDao.class); cityDao1.findByProvinceId("p1"); sqlSession.commit(); }
2016-11-09 11:45:00 - ==> Preparing: select * from city where provinceId = ? 2016-11-09 11:45:00 - ==> Parameters: p1(String) 2016-11-09 11:45:00 - <== Total: 1 2016-11-09 11:45:00 - JDBC Connection 2016-11-09 11:45:00 - ==> Preparing: select * from city where provinceId = ? 2016-11-09 11:45:00 - ==> Parameters: p1(String) 2016-11-09 11:45:00 - <== Total: 1 2016-11-09 11:45:00 - Returning JDBC Connection to DataSource
两个session,分别查询provinceid为p1的city,与数据库交互了两次,这样说明mybatis当前并没有开启二级缓存。
配置如下:
<settings> <setting name="cacheEnabled" value="true" /> </settings>
<mapper namespace="com.area.dao.CityDao"> <select id="findByProvinceId" resultType="city"> select * from city where provinceId = #{pId} </select> <cache/> </mapper>
测试结果
2016-11-09 11:41:11 - ==> Preparing: select * from city where provinceId = ? 2016-11-09 11:41:11 - ==> Parameters: p1(String) 2016-11-09 11:41:12 - <== Total: 1 2016-11-09 11:41:12 - Cache Hit Ratio [com.area.dao.CityDao]: 0.5 2016-11-09 11:41:12 - Returning JDBC Connection to DataSource
只发出一条sql,第二条显示命中缓存,说明二级缓存起到缓存作用
总结:
mybatis
一级缓存:默认开启
二级缓存:
1. 映射语句文件中的所有select语句将会被缓存。
2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。
3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
4. 缓存会根据指定的时间间隔来刷新。
5. 缓存会存储1024个对象