What’s the Difference Between MyBatis First‑Level and Second‑Level Caches?
This article explains the concepts, characteristics, default states, and usage patterns of MyBatis first‑level (SqlSession) and second‑level (Mapper) caches, provides Java code demos for each, and compares their scope, lifecycle, consistency, and suitable scenarios.
MyBatis First‑Level Cache (Local Cache)
The first‑level cache is scoped to a single SqlSession. When the same SqlSession queries the same record repeatedly, MyBatis reads the result from the cache instead of hitting the database each time. It is enabled by default and requires no extra configuration.
Key characteristics:
Cache scope: SqlSession level.
Lifecycle: Exists only for the duration of the SqlSession; it disappears when the session ends.
Automatic eviction: Any insert, update, or delete operation clears the cache to prevent stale data.
Default state: Enabled.
Java example:
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class MyBatisFirstLevelCacheDemo {
public static void main(String[] args) {
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
// Use the same SqlSession
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// First query hits the database
User user1 = mapper.selectUserById(1);
System.out.println(user1);
// Second query uses first‑level cache, no DB hit
User user2 = mapper.selectUserById(1);
System.out.println(user2);
// Any DML clears the cache
mapper.updateUserName(1, "New Name");
sqlSession.commit();
// After commit, cache is cleared; next query hits DB again
User user3 = mapper.selectUserById(1);
System.out.println(user3);
}
}
}⚠️ Note: The first‑level cache is effective only within the same SqlSession . Using a different session invalidates the cache.
MyBatis Second‑Level Cache (Global Cache)
The second‑level cache operates at the Mapper level, allowing cache sharing across multiple SqlSession instances. It is disabled by default and must be explicitly enabled in the mapper XML configuration.
Key characteristics:
Cache scope: Mapper level, shared across SqlSessions.
Lifecycle: Tied to the Mapper’s lifecycle; persists as long as the application runs.
Default state: Disabled; requires manual activation.
Eviction policy: Configurable (e.g., LRU, FIFO, SOFT, WEAK).
Flush interval: Time‑based expiration in milliseconds.
Size: Maximum number of cached objects.
Read‑only flag: When true, cached objects cannot be modified.
Clearing rule: Any insert, update, or delete on the associated Mapper clears its cache.
Mapper XML configuration example:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>Java example:
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class MyBatisSecondLevelCacheDemo {
public static void main(String[] args) {
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
// SqlSession 1
try (SqlSession sqlSession1 = sqlSessionFactory.openSession()) {
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.selectUserById(1); // query DB
System.out.println(user1);
sqlSession1.commit(); // after commit, result is written to second‑level cache
}
// SqlSession 2
try (SqlSession sqlSession2 = sqlSessionFactory.openSession()) {
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.selectUserById(1); // reads from second‑level cache, no DB hit
System.out.println(user2);
}
}
}✅ Key point: The second‑level cache can be shared across SqlSessions but only for the same Mapper, and it is cleared when DML operations affect that Mapper.
Comparison Summary
Both caches improve query performance but differ in scope, lifecycle, default state, and suitable use cases.
Scope: First‑level – SqlSession; Second‑level – Mapper (cross‑SqlSession).
Lifecycle: First‑level – tied to SqlSession; Second‑level – tied to Mapper/application runtime.
Default state: First‑level – enabled; Second‑level – disabled (requires configuration).
Data consistency: Both are invalidated by DML, but first‑level reacts to any SqlSession operation, while second‑level reacts only to DML on the specific Mapper.
Typical scenarios: First‑level – repeated queries within a single transaction; Second‑level – hot data accessed by many transactions or sessions.
When using the caches, remember to configure the second‑level cache parameters (eviction policy, flush interval, size, read‑only) appropriately to avoid cache overflow and ensure data freshness.
java1234
Former senior programmer at a Fortune Global 500 company, dedicated to sharing Java expertise. Visit Feng's site: Java Knowledge Sharing, www.java1234.com
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.
