0
# Cache System
1
2
Multi-level caching system with configurable eviction policies and decorators for performance optimization. MyBatis provides session-level (L1) and global (L2) caching with extensive customization options.
3
4
## Capabilities
5
6
### Cache Interface
7
8
Core caching interface that all cache implementations must implement.
9
10
```java { .api }
11
/**
12
* Basic cache interface for storing and retrieving objects
13
*/
14
interface Cache {
15
/** Get cache identifier */
16
String getId();
17
18
/** Store object in cache */
19
void putObject(Object key, Object value);
20
21
/** Retrieve object from cache */
22
Object getObject(Object key);
23
24
/** Remove object from cache */
25
Object removeObject(Object key);
26
27
/** Clear all cached objects */
28
void clear();
29
30
/** Get current cache size */
31
int getSize();
32
}
33
```
34
35
### Core Cache Implementation
36
37
#### PerpetualCache
38
39
Basic HashMap-based cache implementation that serves as the foundation for all cache decorators.
40
41
```java { .api }
42
/**
43
* Basic HashMap-based cache implementation
44
*/
45
class PerpetualCache implements Cache {
46
/** Create cache with specified ID */
47
public PerpetualCache(String id);
48
49
/** Get cache ID */
50
public String getId();
51
52
/** Get current cache size */
53
public int getSize();
54
55
/** Store object in cache */
56
public void putObject(Object key, Object value);
57
58
/** Retrieve object from cache */
59
public Object getObject(Object key);
60
61
/** Remove specific object from cache */
62
public Object removeObject(Object key);
63
64
/** Clear all cached objects */
65
public void clear();
66
}
67
```
68
69
### Cache Decorators
70
71
MyBatis uses the decorator pattern to add functionality to basic cache implementations.
72
73
#### Eviction Policies
74
75
##### LruCache
76
77
Least Recently Used eviction policy that removes the least recently accessed items when cache reaches size limit.
78
79
```java { .api }
80
/**
81
* LRU (Least Recently Used) eviction policy cache decorator
82
*/
83
class LruCache implements Cache {
84
/** Create LRU cache wrapping another cache implementation */
85
public LruCache(Cache delegate);
86
87
/** Set maximum cache size (default: 1024) */
88
public void setSize(int size);
89
}
90
```
91
92
##### FifoCache
93
94
First In, First Out eviction policy that removes the oldest items when cache reaches size limit.
95
96
```java { .api }
97
/**
98
* FIFO (First In, First Out) eviction policy cache decorator
99
*/
100
class FifoCache implements Cache {
101
/** Create FIFO cache wrapping another cache implementation */
102
public FifoCache(Cache delegate);
103
104
/** Set maximum cache size (default: 1024) */
105
public void setSize(int size);
106
}
107
```
108
109
##### SoftCache
110
111
Uses Java's SoftReference for automatic memory-based eviction when memory is low.
112
113
```java { .api }
114
/**
115
* Soft reference based cache for automatic memory-based eviction
116
*/
117
class SoftCache implements Cache {
118
/** Create soft reference cache wrapping another cache */
119
public SoftCache(Cache delegate);
120
}
121
```
122
123
##### WeakCache
124
125
Uses Java's WeakReference for automatic garbage collection-based eviction.
126
127
```java { .api }
128
/**
129
* Weak reference based cache for automatic GC-based eviction
130
*/
131
class WeakCache implements Cache {
132
/** Create weak reference cache wrapping another cache */
133
public WeakCache(Cache delegate);
134
}
135
```
136
137
#### Time-based Cache Management
138
139
##### ScheduledCache
140
141
Automatically clears cache at specified intervals.
142
143
```java { .api }
144
/**
145
* Time-based cache clearing decorator
146
*/
147
class ScheduledCache implements Cache {
148
/** Create scheduled cache with flush interval */
149
public ScheduledCache(Cache delegate);
150
151
/** Set flush interval in milliseconds */
152
public void setClearInterval(long clearInterval);
153
154
/** Get flush interval */
155
public long getClearInterval();
156
}
157
```
158
159
#### Concurrency and Blocking
160
161
##### SynchronizedCache
162
163
Thread-safe cache wrapper using synchronization.
164
165
```java { .api }
166
/**
167
* Thread-safe cache wrapper using synchronization
168
*/
169
class SynchronizedCache implements Cache {
170
/** Create synchronized cache wrapping another cache */
171
public SynchronizedCache(Cache delegate);
172
}
173
```
174
175
##### BlockingCache
176
177
Prevents cache stampede by blocking concurrent access to the same key during cache miss.
178
179
```java { .api }
180
/**
181
* Blocking cache to prevent cache stampede
182
*/
183
class BlockingCache implements Cache {
184
/** Create blocking cache wrapping another cache */
185
public BlockingCache(Cache delegate);
186
187
/** Set timeout for blocking operations */
188
public void setTimeout(long timeout);
189
}
190
```
191
192
#### Serialization and Storage
193
194
##### SerializedCache
195
196
Stores cached objects in serialized form to reduce memory usage.
197
198
```java { .api }
199
/**
200
* Serialization-based cache storage decorator
201
*/
202
class SerializedCache implements Cache {
203
/** Create serialized cache wrapping another cache */
204
public SerializedCache(Cache delegate);
205
}
206
```
207
208
#### Logging and Monitoring
209
210
##### LoggingCache
211
212
Adds logging capabilities to cache operations for debugging and monitoring.
213
214
```java { .api }
215
/**
216
* Cache decorator with logging capabilities
217
*/
218
class LoggingCache implements Cache {
219
/** Create logging cache wrapping another cache */
220
public LoggingCache(Cache delegate);
221
222
/** Get cache hit ratio */
223
public double getHitRatio();
224
225
/** Get total requests count */
226
public long getRequestCount();
227
228
/** Get cache hits count */
229
public long getHitCount();
230
}
231
```
232
233
#### Transaction Support
234
235
##### TransactionalCache
236
237
Provides transaction-aware caching with rollback support.
238
239
```java { .api }
240
/**
241
* Transaction-aware cache with rollback support
242
*/
243
class TransactionalCache implements Cache {
244
/** Create transactional cache wrapping another cache */
245
public TransactionalCache(Cache delegate);
246
247
/** Commit pending cache operations */
248
public void commit();
249
250
/** Rollback pending cache operations */
251
public void rollback();
252
253
/** Clear pending operations */
254
public void clear();
255
}
256
```
257
258
### Cache Configuration
259
260
#### XML Configuration
261
262
```xml
263
<!-- Global cache settings in mybatis-config.xml -->
264
<configuration>
265
<settings>
266
<setting name="cacheEnabled" value="true"/>
267
<setting name="localCacheScope" value="SESSION"/>
268
</settings>
269
</configuration>
270
271
<!-- Mapper-level cache configuration -->
272
<mapper namespace="com.example.UserMapper">
273
<cache
274
type="org.apache.ibatis.cache.impl.PerpetualCache"
275
eviction="LRU"
276
flushInterval="60000"
277
size="512"
278
readOnly="false"
279
blocking="true"/>
280
281
<select id="findById" resultType="User" useCache="true">
282
SELECT * FROM users WHERE id = #{id}
283
</select>
284
</mapper>
285
```
286
287
#### Annotation Configuration
288
289
```java { .api }
290
/**
291
* Cache namespace configuration annotation
292
*/
293
@interface CacheNamespace {
294
/** Cache implementation class */
295
Class<? extends Cache> implementation() default PerpetualCache.class;
296
297
/** Eviction policy class */
298
Class<? extends Cache> eviction() default LruCache.class;
299
300
/** Flush interval in milliseconds (0 = no automatic flushing) */
301
long flushInterval() default 0;
302
303
/** Maximum number of cached objects */
304
int size() default 1024;
305
306
/** Read/write cache (true) or read-only cache (false) */
307
boolean readWrite() default true;
308
309
/** Use blocking cache to prevent cache stampede */
310
boolean blocking() default false;
311
312
/** Additional cache properties */
313
Property[] properties() default {};
314
}
315
316
/**
317
* Cache namespace reference annotation
318
*/
319
@interface CacheNamespaceRef {
320
/** Referenced mapper class */
321
Class<?> value() default void.class;
322
323
/** Referenced namespace name */
324
String name() default "";
325
}
326
327
/**
328
* Cache property configuration
329
*/
330
@interface Property {
331
/** Property name */
332
String name();
333
334
/** Property value */
335
String value();
336
}
337
```
338
339
**Usage Examples:**
340
341
```java
342
@CacheNamespace(
343
implementation = PerpetualCache.class,
344
eviction = LruCache.class,
345
flushInterval = 300000, // 5 minutes
346
size = 1024,
347
readWrite = true,
348
blocking = true,
349
properties = {
350
@Property(name = "compression", value = "true"),
351
@Property(name = "serialization", value = "java")
352
}
353
)
354
public interface UserMapper {
355
@Select("SELECT * FROM users WHERE id = #{id}")
356
@Options(useCache = true)
357
User findById(@Param("id") Long id);
358
359
@Select("SELECT * FROM users WHERE status = #{status}")
360
@Options(useCache = true, flushCache = false)
361
List<User> findByStatus(@Param("status") String status);
362
363
@Update("UPDATE users SET name = #{name} WHERE id = #{id}")
364
@Options(flushCache = true)
365
int updateName(@Param("id") Long id, @Param("name") String name);
366
}
367
368
// Reference cache from another mapper
369
@CacheNamespaceRef(UserMapper.class)
370
public interface UserProfileMapper {
371
@Select("SELECT * FROM user_profiles WHERE user_id = #{userId}")
372
UserProfile findByUserId(@Param("userId") Long userId);
373
}
374
```
375
376
### Custom Cache Implementation
377
378
Creating custom cache implementations for specialized requirements.
379
380
```java
381
public class RedisCacheImpl implements Cache {
382
private final String id;
383
private final RedisTemplate<String, Object> redisTemplate;
384
private final String keyPrefix;
385
386
public RedisCacheImpl(String id) {
387
this.id = id;
388
this.redisTemplate = ApplicationContextHolder.getBean(RedisTemplate.class);
389
this.keyPrefix = "mybatis:cache:" + id + ":";
390
}
391
392
@Override
393
public String getId() {
394
return id;
395
}
396
397
@Override
398
public void putObject(Object key, Object value) {
399
String redisKey = keyPrefix + key.toString();
400
redisTemplate.opsForValue().set(redisKey, value, Duration.ofMinutes(30));
401
}
402
403
@Override
404
public Object getObject(Object key) {
405
String redisKey = keyPrefix + key.toString();
406
return redisTemplate.opsForValue().get(redisKey);
407
}
408
409
@Override
410
public Object removeObject(Object key) {
411
String redisKey = keyPrefix + key.toString();
412
Object value = redisTemplate.opsForValue().get(redisKey);
413
redisTemplate.delete(redisKey);
414
return value;
415
}
416
417
@Override
418
public void clear() {
419
Set<String> keys = redisTemplate.keys(keyPrefix + "*");
420
if (keys != null && !keys.isEmpty()) {
421
redisTemplate.delete(keys);
422
}
423
}
424
425
@Override
426
public int getSize() {
427
Set<String> keys = redisTemplate.keys(keyPrefix + "*");
428
return keys != null ? keys.size() : 0;
429
}
430
}
431
432
// Usage with annotation
433
@CacheNamespace(implementation = RedisCacheImpl.class)
434
public interface ProductMapper {
435
@Select("SELECT * FROM products WHERE id = #{id}")
436
Product findById(@Param("id") Long id);
437
}
438
```
439
440
### Cache Key Generation
441
442
Understanding how MyBatis generates cache keys for proper cache behavior.
443
444
```java { .api }
445
/**
446
* Cache key generation and management
447
*/
448
class CacheKey implements Cloneable, Serializable {
449
/** Create new cache key */
450
public CacheKey();
451
452
/** Create cache key with base components */
453
public CacheKey(Object[] objects);
454
455
/** Update cache key with additional component */
456
public void update(Object object);
457
458
/** Update cache key with all components from list */
459
public void updateAll(Object[] objects);
460
461
/** Clone this cache key */
462
public CacheKey clone() throws CloneNotSupportedException;
463
}
464
```
465
466
### Cache Statistics and Monitoring
467
468
Monitoring cache performance and hit rates.
469
470
```java
471
// Cache statistics example
472
@CacheNamespace(
473
implementation = PerpetualCache.class,
474
eviction = LruCache.class,
475
size = 1000
476
)
477
public interface OrderMapper {
478
@Select("SELECT * FROM orders WHERE id = #{id}")
479
@Options(useCache = true)
480
Order findById(@Param("id") Long id);
481
}
482
483
// Monitoring cache performance
484
public class CacheMonitor {
485
public void printCacheStats(Configuration configuration) {
486
Collection<Cache> caches = configuration.getCaches();
487
488
for (Cache cache : caches) {
489
if (cache instanceof LoggingCache) {
490
LoggingCache loggingCache = (LoggingCache) cache;
491
System.out.println("Cache: " + cache.getId());
492
System.out.println("Hit Ratio: " + loggingCache.getHitRatio());
493
System.out.println("Total Requests: " + loggingCache.getRequestCount());
494
System.out.println("Cache Hits: " + loggingCache.getHitCount());
495
}
496
}
497
}
498
}
499
```
500
501
## Types
502
503
```java { .api }
504
/**
505
* Local cache scope options
506
*/
507
enum LocalCacheScope {
508
/** Cache scoped to SqlSession (default) */
509
SESSION,
510
511
/** Cache scoped to individual statements */
512
STATEMENT
513
}
514
515
/**
516
* Cache-related exceptions
517
*/
518
class CacheException extends PersistenceException {
519
public CacheException(String message);
520
public CacheException(String message, Throwable cause);
521
}
522
523
/**
524
* Cache statistics interface
525
*/
526
interface CacheStats {
527
/** Get cache hit count */
528
long getHitCount();
529
530
/** Get cache miss count */
531
long getMissCount();
532
533
/** Get total request count */
534
long getRequestCount();
535
536
/** Get hit ratio (hits / total requests) */
537
double getHitRatio();
538
539
/** Reset statistics */
540
void reset();
541
}
542
```