Caching mechanism of Mybatis

Posted by sebajom on Tue, 08 Mar 2022 22:44:48 +0100

cache

MyBatis has built-in a powerful transactional query caching mechanism, which can be easily configured and customized.

By default, only local session caching is enabled, which only caches the data in one session. To enable the global L2 cache, you only need to add a line to the mapping file of SQL:
<cache/>

L1 cache

Also known as local cache, it is only valid in SqlSession once (it is on by default)
The data queried during the same session with the database will be placed in the local cache
If you need to get the same data in the future, you can get it directly from the cache without querying the database

Failure conditions:
  • sqlSession is different
  • Sqlsessions are the same, but queries are different
  • sqlSession is the same, and additions, deletions and modifications have been made between the two same queries
  • The L1 cache was manually cleared
sqlSession.clearCache();

testing procedure

  1. Open log
    It is convenient to observe the query process
  2. The test queries the same record twice in an SQLsession
 @Test
    public void test6(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User userByID = mapper.getUserByID(1);
        System.out.println("userByID = " + userByID);
        User userByID2 = mapper.getUserByID(1);
        System.out.println("userByID2 = " + userByID2);
        System.out.println(userByID2==userByID);
        mapper.addUser(new User(11,"Li Zongsheng","lizongsheng"));
        mapper.addUser(new User(12,"Lin Yilian","linyilian"));
        User userByID3 = mapper.getUserByID(1);
        System.out.println("userByID3 = " + userByID3);
        System.out.println(userByID3==userByID);

        mapper.deleteUser(5);
        sqlSession.close();
    } 
  1. View log output

L2 cache

As long as the L2 cache is enabled, it is effective under the same MApper
All data will be put in the first level cache first
Only when the session is submitted or closed, it will be submitted to the L2 cache

Steps to enable L2 cache:

Step 1: explicitly open the global configuration in the mybatis config core configuration file

    <settings>
<!--    Explicitly turn on global cache    -->
        <setting name="cacheEnable" value="true"/>
<!--    Standard log factory implementation    -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        <setting name="logImpl" value="LOG4J"/>-->
    </settings>

Step 2: mapper Add cache tag in XML
It can also be set for each query statement, which is rarely used

Step 3: All entity classes should implement serializable interfaces

public class User implements Serializable {
    private int id;
    private String name;
    private String password;
}
Some parameters in cache (generally not used)
<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

This more advanced configuration creates a FIFO cache, which is refreshed every 60 seconds. It can store up to 512 references of the result object or list, and the returned objects are considered read-only. Therefore, modifying them may conflict with callers in different threads.

Cache principle

First, the query will first check whether there is any in the L2 cache. If there is no L1 cache, the database will be checked if there is no L1 cache. After finding it, the results will be put into the L1 cache. After the current session ends, the cached data in the L1 cache will be transferred to the L2 cache

Second level cache ehcache provided by a third party

Step 1: import dependencies

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
</dependency>

Step 2: mapper Implementation of setting cache in cache tag of XML

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

Step 3: create ehcache xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <diskStore path="./tmpdir/Tmp_EhCache"/>
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
</ehcache>

ehcache.xml configuration information can be searched online

diskStore :  ehcache Memory and disk storage are supported
path : Specify the location of disk storage
defaultCache :  Default cache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
cache : Self defined cache. When the self-defined configuration does not meet the actual situation, it can be customized (multiple cache can be included) cache Node)

name : The name of the cache. You can get the specified one by specifying the name Cache object

maxElementsInMemory : The maximum number of elements allowed to be stored in memory. 0 represents infinite

clearOnFlush: Whether to clear when the amount of memory is maximum.

eternal : Set whether the object in the cache is permanent. If so, the timeout setting will be ignored and the object will never expire. According to the difference of stored data, for example, some static data, such as provinces and cities, can be set to never be outdated

timeToIdleSeconds :  Set the allowed idle time of the object before expiration (unit: seconds). Only if eternal=false It is used when the object is not permanently valid. It is an optional attribute. The default value is 0, that is, the idle time is infinite.

timeToLiveSeconds : Lifetime of cached data( TTL),That is, the maximum time interval value of an element from construction to extinction, which is valid only when the element does not reside permanently. If the value is 0, it means that the element can pause for an infinite time.

overflowToDisk : Whether to enable disk caching when there is insufficient memory.

maxEntriesLocalDisk: When the number of objects in memory reaches maxElementsInMemory When, Ehcache Write objects to disk.

maxElementsOnDisk: Maximum number of hard disk caches.

diskSpoolBufferSizeMB: This parameter setting DiskStore(Cache size of disk cache). The default is 30 MB. each Cache Each should have its own buffer.

diskPersistent: Is it VM Store the cached data of the hard disk when restarting. The default value is false. 

diskExpiryThreadIntervalSeconds: The running time interval of disk failure thread is 120 seconds by default.

Topics: Java Mybatis