Unlock MyBatis Performance: Master First- and Second-Level Caches
This article demystifies MyBatis’s caching system, explaining the architecture of first- and second-level caches, how SqlSession, Executor and Cache interact, key generation rules, configuration steps, and best practices for achieving optimal database query performance.
01 MyBatis Cache Architecture Overview
MyBatis provides a powerful cache mechanism to significantly improve database query performance. It adopts a two‑level cache architecture similar to CPU L1/L2 caches. The diagram below gives a high‑level view of the architecture.
02 First‑Level Cache Mechanism
When a SqlSession is opened, MyBatis creates a local cache inside the session. Re‑executing the same query within the same SqlSession will first check this local cache; if a matching result exists, it is returned directly without hitting the database, reducing resource consumption.
The SqlSession delegates actual database work to an Executor. The Executor holds a Cache implementation (typically PerpetualCache) which internally uses a simple HashMap<k, v> to store query results.
When the session ends, the SqlSession, its Executor, and the associated cache are all released. The following methods can manually clear the first‑level cache:
close(): releases the cache.
clearCache(): empties the cache but keeps it usable.
update/insert/delete: also clear the cache.
A cache entry is identified by a key composed of the statement ID, row bounds, the bound SQL string, and the parameter values. Only when all these match are two queries considered identical.
03 Second‑Level Cache Mechanism
The second‑level cache is shared across SqlSessions at the application level. When cacheEnabled=true in the global configuration, MyBatis wraps the Executor with a CachingExecutor. Queries first check the second‑level cache; if missing, the underlying Executor runs the query and the result is stored in the second‑level cache for future use.
The second‑level cache is scoped per Mapper. Each Mapper can define its own <cache> element, or share a cache via <cache-ref>. To enable caching for a specific query, the useCache="true" attribute must be set on the <select> statement.
Effective second‑level caching requires:
Global cacheEnabled=true setting.
The Mapper containing the query declares a cache (or cache‑ref).
The <select> statement has useCache=true.
When configured, MyBatis checks the second‑level cache first, then the first‑level cache, and finally the database.
04 Cache Implementation Options
MyBatis ships with built‑in cache implementations supporting strategies such as LRU and FIFO. Developers can also provide a custom implementation of org.apache.ibatis.cache.Cache and reference it via the type attribute of <cache>. Integration with third‑party caches like Memcached is also possible.
Note that cache invalidation is scoped to the Mapper that performed the update. Other Mappers may still return stale data unless their caches are explicitly cleared after modifications.
Summary
MyBatis’s layered cache design—combining a session‑level first‑level cache with an application‑wide second‑level cache—offers flexible performance optimization. By understanding the architecture, key generation rules, configuration requirements, and cache granularity, developers can fine‑tune query speed and resource usage.
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.
Programmer Null's Self-Cultivation
Focused on backend development technologies and sharing knowledge from programming project experiences.
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.
