实践mybatis缓存

mybatis-cache-architecture

一级缓存

SqlSession级别【SQLSessionTemplate和SQLSessionDaoSupport每次都获取新的SQLSession】,默认打开状态,无法关闭(除非自定义插件控制)。

示例:

1
2
3
4
5
6
7
8
9
public City selectCityById(long id) {
	SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) sqlSession;
	SqlSession s = sqlSessionTemplate.getSqlSessionFactory().openSession();
	City city = s.selectOne("selectCityById", id);
	// 因为一级缓存,下面的sql不会执行
	City city1 = s.selectOne("selectCityById", id);
	s.close();
	return city;
}

二级缓存

Application级别,默认关闭状态。通过如下步骤开启二级缓存:

1.  MyBatis支持二级缓存的总开关:全局配置变量参数cacheEnabled=truecacheEnabled的默认值是true。 2.  该select语句所在的Mapper,配置了<cache><cached-ref>节点,并且有效。 3.  该select语句的参数 useCache=trueuseCache的默认值是true。

示例:

CityMapper.xml

1
2
3
4
5
6
<mapper namespace="wang.angi.sample.mybatis.spring.boot.starter.mapper.CityMapper">
    <cache/>
    <select id="selectCityById" resultType="City">
        select * from city where id = #{id}
    </select>
</mapper>

Java:

1
2
3
4
5
System.out.println(this.CityMapper.selectCityById(1));
// 打开二级缓存,下面的三条sql不会执行
System.out.println(this.CityMapper.selectCityById(1));
System.out.println(this.CityMapper.selectCityById(1));
System.out.println(this.CityMapper.selectCityById(1));

日志:

1
2
3
4
5
6
7
8
9
10
11
2019-12-26 10:53:07.043 DEBUG 11454 --- [           main] w.a.s.m.s.b.starter.mapper.CityMapper    : Cache Hit Ratio [wang.angi.sample.mybatis.spring.boot.starter.mapper.CityMapper]: 0.0
2019-12-26 10:53:07.044 DEBUG 11454 --- [           main] w.a.s.m.s.b.s.m.C.selectCityById         : ==>  Preparing: select * from city where id = ? 
2019-12-26 10:53:07.046 DEBUG 11454 --- [           main] w.a.s.m.s.b.s.m.C.selectCityById         : ==> Parameters: 1(Long)
2019-12-26 10:53:07.046 TRACE 11454 --- [           main] w.a.s.m.s.b.s.m.C.selectCityById         : <==    Columns: ID, NAME, STATE, COUNTRY, CREATED_BY
2019-12-26 10:53:07.046 TRACE 11454 --- [           main] w.a.s.m.s.b.s.m.C.selectCityById         : <==        Row: 1, San Francisco, CA, US, Angi
2019-12-26 10:53:07.047 DEBUG 11454 --- [           main] w.a.s.m.s.b.s.m.C.selectCityById         : <==      Total: 1
2019-12-26 10:53:07.050 DEBUG 11454 --- [           main] w.a.s.m.s.b.starter.mapper.CityMapper    : Cache Hit Ratio [wang.angi.sample.mybatis.spring.boot.starter.mapper.CityMapper]: 0.5
1,San Francisco,CA,US,Angi
2019-12-26 10:53:07.050 DEBUG 11454 --- [           main] w.a.s.m.s.b.starter.mapper.CityMapper    : Cache Hit Ratio [wang.angi.sample.mybatis.spring.boot.starter.mapper.CityMapper]: 0.6666666666666666
2019-12-26 10:53:07.051 DEBUG 11454 --- [           main] w.a.s.m.s.b.starter.mapper.CityMapper    : Cache Hit Ratio [wang.angi.sample.mybatis.spring.boot.starter.mapper.CityMapper]: 0.75
1,San Francisco,CA,US,Angi

insert/update/delete等有一个属性flushCache,默认值是true

<cache/>

<!ELEMENT cache (property*)>
<!ATTLIST cache
type CDATA #IMPLIED
eviction CDATA #IMPLIED
flushInterval CDATA #IMPLIED
size CDATA #IMPLIED
readOnly CDATA #IMPLIED
blocking CDATA #IMPLIED
>

<cache-ref/>

<!ELEMENT cache-ref EMPTY>
<!ATTLIST cache-ref
namespace CDATA #REQUIRED
>

参考

《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项

《深入理解mybatis原理》 MyBatis的二级缓存的设计原理