What Is the MyBatis Second-Level Cache?

MyBatis is an open-source, lightweight persistence framework for the Java programming language. Unlike full object-relational mapping (ORM) frameworks such as Hibernate, MyBatis lets developers write SQL statements and stored procedures directly and then maps the results to Java objects — giving fine-grained control over exactly how the database is queried.

Part of MyBatis' performance comes from caching query results so they can be reused instead of hitting the database again. MyBatis has two cache levels, and the shared one is called the "second-level cache" or "L2 cache." So what is the MyBatis second-level cache, and how should you use it?

MyBatis Second-Level Cache Definition

The MyBatis second-level cache is an L2 cache implemented for the MyBatis framework. In our article on cache memory, we discuss how cached data is commonly organized into tiers:

  • The L1 cache is the smallest and closest tier, checked first for the fastest possible lookups.
  • The L2 cache is larger and slightly slower. If the requested data is not in the L1 cache, the application checks the L2 cache next.

In MyBatis, the first-level cache plays the role of the L1 tier and is scoped to a single session, while the second-level cache plays the role of the L2 tier and is shared across sessions. The next section looks at how each one works.

How Does the MyBatis Second-Level Cache Work?

MyBatis checks the first-level cache before it checks the second-level cache.

The first-level (local) cache is enabled by default and is tied to a SqlSession — the object representing a connection between the application and the database. Results are reused only within that session, and the cache is cleared when the session is updated, committed, or closed. Data does not persist across sessions.

The second-level cache is optional and namespace-scoped. You enable it by adding a <cache> element to a mapper (MyBatis caching must also be switched on globally, which it is by default). The second-level cache is transactional, so a session's results are written to the shared cache when that session is committed; from there, other sessions querying the same mapper namespace can reuse them. A namespace can also share another namespace's cache through a <cache-ref> element.

MyBatis' built-in second-level cache accepts several attributes on the <cache> element, including eviction (LRU by default, as well as FIFO, SOFT, and WEAK), flushInterval, size, and readOnly. Cached objects should be serializable when the cache is not read-only.

By default, this second-level cache is an in-process, per-JVM store. That works for a single instance, but in a clustered deployment each node keeps its own copy — so cache hit rates fall and cache invalidation becomes inconsistent across the fleet. Backing the second-level cache with an external store turns it into a distributed cache that every node shares.

MyBatis Second-Level Caching With Valkey or Redis

Redis and Valkey are open-source, in-memory data structure stores widely used to build NoSQL key-value databases and caches. Neither supports the Java programming language out of the box, so many developers use a third-party Java client such as Redisson.

The Redisson client offers full support for MyBatis second-level caching through its redisson-mybatis module, which is compatible with MyBatis 3.0.0 and above. To use it, set the mapper's cache type to a Redisson implementation and configure it with <property> elements:

<cache type="org.redisson.mybatis.RedissonCache">
    <property name="timeToLive" value="200000"/>
    <property name="maxIdleTime" value="100000"/>
    <property name="maxSize" value="100000"/>
    <property name="redissonConfig" value="redisson.yaml"/>
</cache>

With this in place, query results are stored in Valkey or Redis and shared across every application node. Redisson applies timeToLive, maxIdleTime, and maxSize limits per entry, giving finer control than the caching extension bundled with MyBatis, which expires the cache as a whole. Redisson PRO adds two further options: a local (near) cache that serves hot reads from application memory up to 45 times faster, and data partitioning that spreads a single cache across multiple cluster nodes to scale memory and throughput.

To learn how to set up MyBatis second-level caching with Valkey or Redis step by step, see our tutorial on Caching in MyBatis With Valkey or Redis and the Cache API implementations documentation.

Similar Terms