Master MyBatis Caching: First- and Second-Level Cache Explained
This article explains MyBatis caching fundamentals, detailing first- and second-level cache concepts, configuration, cache invalidation scenarios, and custom cache integration with EHCache, supplemented by practical code snippets and quiz questions to illustrate cache behavior across SqlSessions.
Common Concepts in MyBatis Cache
Key objects involved in MyBatis caching:
SqlSession : Represents a single database session and provides methods to execute statements.
MappedStatement : Abstract representation of a SQL command that will be executed.
Executor : Executes statements against the database; receives a MappedStatement as a parameter.
namespace : Each mapper file defines one namespace; caches can be shared at the mapper (namespace) level.
Mapping Interface : Java interface whose methods correspond to SQL statements defined in XML mapper files.
Mapping File : XML file containing one or more SQL statements, typically one file per database table.
First-Level Cache (Session Scope)
Principle
Within a single SqlSession, if the same query is executed repeatedly without any intervening insert, update, or delete, MyBatis returns the result from the local cache instead of hitting the database.
Each SqlSession holds an Executor that contains a LocalCache. The cache is essentially a HashMap:
private Map<Object, Object> cache = new HashMap<>();The cache key is composed of: StatementId + Offset + Limit + SQL + Parameters The cache value is the query result.
Configuration
Set the localCacheScope attribute in mybatis-config.xml:
<configuration>
<settings>
<setting name="localCacheScope" value="SESSION"/>
</settings>
</configuration> SESSIONenables first‑level cache for the entire SqlSession. STATEMENT disables caching for the current statement.
Cache Invalidation Scenarios
Different SqlSession instances have independent first‑level caches.
Same SqlSession but different query parameters produce different cache keys.
Any insert, update, or delete operation between two queries in the same SqlSession clears the related cache entry.
Manual clearing of the cache via sqlSession.clearCache().
Second-Level Cache (Namespace Scope)
Overview
The second‑level cache shares cached data across multiple SqlSession instances at the mapper namespace level. It is implemented by the Cache interface and wrapped by a CachingExecutor.
Principle
When enabled, MyBatis decorates the original Executor with a CachingExecutor. Query processing follows this order:
Check the second‑level cache.
If missed, check the first‑level (session) cache.
If still missed, query the database.
When the SqlSession is closed, entries from the first‑level cache are written to the second‑level cache.
Configuration
Enable the second‑level cache globally in mybatis-config.xml:
<setting name="cacheEnabled" value="true"/>To activate a second‑level cache for a specific mapper, add a <cache> element in the mapper XML:
<cache type="org.apache.ibatis.cache.impl.PerpetualCache"/>Custom Cache Implementation
Overview
If the built‑in second‑level cache does not satisfy requirements, you can implement a custom cache by creating a class that implements org.apache.ibatis.cache.Cache. The interface defines seven methods:
String getId() void putObject(Object key, Object value) Object getObject(Object key) Object removeObject(Object key) void clear() int getSize() ReadWriteLock getReadWriteLock()Integrating EHCache
EHCache provides a ready‑made Cache implementation for MyBatis.
Add the Maven dependency:
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>Create an ehcache.xml configuration file (example):
<?xml version="1.0" encoding="utf-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="D:/passjava/ehcache"/>
<defaultCache maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>Enable EHCache for a mapper by adding the cache element:
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>References
Technical article: https://tech.meituan.com/2018/01/19/mybatis-cache.html
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
