在很多场合中需要用到数据库缓存。 此文档简单描述如何在spring + mybatis场合下配置缓存。
Mybatis提供功能强大的缓存机制。缓存共可以分为两类:一级缓存和二级缓存。一级缓存是SqlSession级别的,二级缓存为整个应用级别,即一个数据源级别。
缓存的具体实现可以有以下几种方式:
配置了缓存的整个数据获取优先级为: 二级缓存–>一级缓存–>数据库
默认情况下,缓存开关为开,因此可以不配置。可以通过以下方式显式配置。
配置SqlSessionFactoryBean中指定配置mybatis文件:
<bean id="epingSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="epingDataSource" />
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
bean>
mybatis配置sqlMapConfig.xml,该文件放于src/main/resources目录下:
<configuration>
<settings>
<setting name="cacheEnabled" value="false" />
settings>
configuration>
在mybatis-spring 1.3以后,可以直接在SqlSessionFactoryBean配置,无需使用mybatis的xml形式。
要使用mybatis缓存,需要打开一个全局开关,在非spring场合下,在mybatis的配置中使用settings元素打开全局缓存开关。
在Spring中,可以将属性在SqlSessionFactory的工厂Bean中配置,一个例子如下:
<bean id="epingSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="epingDataSource" />
<property name="configurationProperties">
<props>
<prop key="cacheEnabled">trueprop>
props>
property>
bean>
configurationProperties等效于MyBatis配置中的properties元素,这些属性值将用于解析配置文件中占位符的解析。上述配置等同于:
<properties>
<property name="cacheEnabled" value="true"/>
properties>
这里的cacheEnabled可以在myabtis的xml配置中使用:
<setting name="cacheEnabled" value="${cacheEnabled}" />
更多MyBatis的属性配置参考: http://www.mybatis.org/mybatis-3/configuration.html#properties
二级缓存是针对Mapper范围的,更具体地说,是针对一个namespace,也就是说每个namespacce都可以配置一个缓存对象, 多个namespace也可以共享一个缓存对象。具体配置如下:
<cache readOnly="true" flushInterval="3600000">cache>
缓存对象可以配置大小,溢出策略,刷新时间间隔等属性。
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
如果使用自定义的内存实现,使用type属性指向自定义类。
如果需要在多个namespace之间共享缓存对象,使用
<cache-ref namespace="com.someone.application.data.SomeMapper"/>
更多配置请参考 http://www.mybatis.org/mybatis-3/sqlmap-xml.html#cache
配置完缓存后,还需要指定某个特定的SQL语句是否使用缓存,使用useCache属性,如下:
<select id="selectByPage" parameterType="com.yiping.common.core.page.Page"
resultMap="BaseResultMap" useCache="true">
select * from bas_doctor
<if test="whereClause != null">
${whereClause}
if>
<if test="page != null">
limit #{page.begin} , #{page.length}
if>
select>
除了定期刷新缓存外,如果调用Mapper中的语句执行插入、删除、更新操作,都会使得该Mapper对应的缓存失效。 各语句是否刷新缓存通过flushCache属性来配置,如select语句该值默认为false。