答案就是不能禁用,呵呵。 ------------------------------- 一级缓存分为statement和session两种,默认是后者。 可以改成statement,这样语句执行完就会清空缓存。
(1)指定mybatis配置文件路径
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml" />
springboot在配置文件这样写: mybatis.config-locations=classpath:mybatis-config.xml
(2)配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="localCacheScope" value="STATEMENT" /> </settings>
</configuration>
(3)发现可以这样: select语句: 默认flushCache="false" useCache="true",表示缓存结果,不清空缓存
insert,update,delete: 默认flushCache="true" ,表示清空缓存
在mapper里 <select id="save" parameterType="XX" flushCache="true" useCache="false"> 那么就不缓存这个select结果了,简单试了下,貌似有用。 ======================================== 一级缓存默认开启,session级别(需要开启事务,否则不好使),无法禁用。 <setting name="localCacheScope" value="SESSION" /> <setting name="localCacheScope" value="STATEMENT" />
二级缓存默认开启,但是mapper.xml里需要写<cache/>来激活。 <setting name="cacheEnabled" value="true"/>
配置参数: https://mybatis.org/mybatis-3/configuration.html#settings ------------------------------------------------- org.apache.ibatis.executor.BaseExecutor
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if (closed) { throw new ExecutorException("Executor was closed."); } if (queryStack == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List<E> list; try { queryStack++; list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; if (list != null) { handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); } else { list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); } } finally { queryStack--; } if (queryStack == 0) { for (DeferredLoad deferredLoad : deferredLoads) { deferredLoad.load(); } // issue #601 deferredLoads.clear(); if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) { // issue #482 clearLocalCache(); } } return list; }
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List<E> list; localCache.putObject(key, EXECUTION_PLACEHOLDER); try { list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); } finally { localCache.removeObject(key); } localCache.putObject(key, list); if (ms.getStatementType() == StatementType.CALLABLE) { localOutputParameterCache.putObject(key, parameter); } return list; }
开始,FlushCache为true会清缓存。 queryFromDatabase方法里面,会put进缓存。也不判断一下是否useCache,直接就放,有点彪啊。 LocalCacheScope为STATEMENT,会清缓存。 但是注意queryStack这个变量,为0时才清缓存。 并发查询,最后那个才清理缓存?中间就一直灌内存?
|