MyBatis: query cache

Query cache

The scope of Mybatis first-level cache is the same SqlSession. The same SQL statement is executed twice in the same sqlSession. After the first execution, the data queried in the database will be written to the cache (memory), and the second time will be obtained from the cache Data will no longer be queried from the database, thereby improving query efficiency. When a sqlSession ends, the first-level cache in the sqlSession does not exist. Mybatis enables the first-level cache by default. 

The Mybatis secondary cache is shared by multiple SqlSessions, and its scope is the same namespace of the mapper. Different sqlSessions execute the sql statement under the same namespace twice and pass the same parameters to the sql, which ultimately executes the same sql statement. Once the execution is completed, the data queried in the database will be written to the cache (memory), and the second time the data will be obtained from the cache will not be queried from the database, thereby improving query efficiency. Mybatis does not enable the secondary cache by default. You need to enable the secondary cache in the setting global parameters.

Level 1 cache

The first-level cache area is divided according to SqlSession.

Each query will first be found in the cache area. If no query from the database is found, the data will be written to the cache when the query is found.

Mybatis internal storage cache uses a HashMap, key is hashCode + sqlId + Sql statement, and value is a java object generated from the query mapping.

After sqlSession performs insert, update, delete and other operations, the commit area will be cleared after the commit is submitted.

Secondary cache

The secondary cache area is divided according to the namespace of the mapper. Mapper query data of the same namespace is placed in the same area. If the mapper proxy method is used, each mapper's namespace is different. At this time, it can be understood that the secondary cache area is divided according to the mapper .

Each query will first be found in the cache area. If no query from the database is found, the data will be written to the cache when the query is found.

Mybatis internal storage cache uses a HashMap, key is hashCode + sqlId + Sql statement. value is the java object generated by the mapping from the query

After sqlSession performs insert, update, delete and other operations, the commit area will be cleared after the commit is submitted.

Turn on secondary cache

Add in the core configuration file SqlMapConfig.xml

<setting name="cacheEnabled" value="true"/>

 

description

allowance

Defaults

cacheEnabled

Set global on / off settings for all caches under this configuration file.

true false

true

To add a line in your Mapper mapping file: <cache />, which means that this mapper enables secondary cache.

The secondary cache needs the pojo object mapped by the query result to implement the java.io.Serializable interface to implement serialization and deserialization operations. Note that if there is a parent class, the member pojo needs to implement the serialization interface.

public class Orders implements Serializable
public class User implements Serializable

Disable secondary cache

Setting useCache = false in the statement can disable the second-level cache of the current select statement, that is, every query will issue sql to query. The default is true, that is, the sql uses the second-level cache.

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

Refresh the cache

In the same namespace of mapper, if there are other insert, update, and delete operation data, the cache needs to be refreshed. If the cache is not refreshed, a dirty read will occur.

Set the flushCache = "true" property in the statement configuration. By default, it is true to refresh the cache. If it is changed to false, it will not be refreshed. When using the cache, if you manually modify the query data in the database table, there will be dirty reads.

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

MyBatis Cache parameters

flushInterval (refresh interval) can be set to any positive integer, and they represent a reasonable time period in the form of milliseconds. By default, it is not set, that is, there is no refresh interval, and the cache is refreshed only when the statement is called.

size (number of references) can be set to any positive integer, remember the number of objects you cache and the number of available memory resources in your running environment. The default value is 1024.

The readOnly attribute can be set to true or false. A read-only cache will return the same instance of the cache object to all callers. Therefore these objects cannot be modified. This provides a very important performance advantage. The read-write cache will return a copy of the cached object (through serialization). This will be slower, but safe, so the default is false.

 <cache  eviction="FIFO"  flushInterval="60000"  size="512"  readOnly="true"/>

This more advanced configuration creates a FIFO buffer and refreshes it every 60 seconds, storing 512 references to the result object or list, and the returned object is considered read-only, so between callers in different threads Modifying them will cause conflicts. Available recovery strategies are, the default is LRU:

  • LRU-least recently used: remove objects that have not been used for the longest time.
  • FIFO – first-in-first-out: remove objects in the order they enter the cache.
  • SOFT-Soft reference: remove objects based on garbage collector status and soft reference rules.
  • WEAK-Weak Reference: More aggressively remove objects based on garbage collector status and weak reference rules.

MyBatis integration Ehcache

EhCache is a pure Java in-process cache framework. It is a widely used open source Java distributed cache. It has the characteristics of fast and lean, and is the default CacheProvider in Hibernate.

Integration: The personal R & D part of the software is delivered to the overall part of the software in order to discover the problems of the personal development part as early as possible.

Deployment: The code is delivered to the runnable development / test section as soon as possible, so that it can be tested as early as possible.

Delivery: R & D is delivered to customers as soon as possible in order to discover problems in the production environment as soon as possible.

Distributed: A service is split into multiple sub-services and deployed on different servers.

Cluster deployment: The same service is deployed on multiple servers.

Mybatis integration ehcache principle

Mybatis provides a secondary cache interface, as follows:

 

Its default implementation class:

By implementing the Cache interface, mybatis cache data can be integrated through other cache databases. The specialty of mybatis is sql operation. The management of cached data is not the specialty of mybatis. To improve the performance of the cache, mybatis and third-party cache databases are integrated, such as ehcache, memcache , Redis, etc.

Step 1: Introduce cached dependencies

maven坐标:
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.2</version>
</dependency>

Step 2: Introduce cache configuration file

Add under classpath: ehcache.xml, the content is as follows:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore path="F:\\develop\\ehcache" />
    <defaultCache 
        maxElementsInMemory="1000" 
        maxElementsOnDisk="10000000"
        eternal="false" 
        overflowToDisk="true" 
        timeToIdleSeconds="120"
        timeToLiveSeconds="120" 
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

Property description:

  • diskStorel: Specifies the storage location of data in the disk
  • defaultCachel: When creating Cache with the help of CacheManager.add ("demoCache"), EhCache will adopt the management strategy specified by <defalutCache />

The following attributes are required:

  • maxElementsInMemory-the maximum number of elements cached in memory 
  • maxElementsOnDisk-the maximum number of elements cached on the disk, if 0 means infinity
  • eternal-Set whether the cached elements will never expire. If it is true, the cached data is always valid, if it is false, it must be judged according to timeToIdleSeconds, timeToLiveSeconds
  • overflowToDisk-Set whether to cache expired elements to disk when the memory cache overflows

The following attributes are optional:

  • timeToIdleSeconds-When the time of two visits before and after the data cached in EhCache exceeds the value of the timeToIdleSeconds property, the data will be deleted. The default value is 0, which is the idle time infinite
  • timeToLiveSeconds-the effective lifetime of the cache element, the default is 0, that is, the element survival time is infinite
  • diskSpoolBufferSizeMB-This parameter sets the size of the DiskStore (disk cache) buffer area, the default is 30MB, each Cache should have its own buffer
  • diskPersistent-Whether to enable the disk to save data in EhCache when the VM restarts, the default is false
  • diskExpiryThreadIntervalSeconds-Disk cache cleaning thread running interval, the default is 120 seconds. Every 120s, the corresponding thread will clean up the data in EhCache
  • memoryStoreEvictionPolicy-When the memory cache reaches the maximum, when a new element is added, remove the element's strategy from the cache. The default is LRU (least recently used), optional LFU (least frequently used) and FIFO (first in first out)

Step 3: Turn on ehcache

EhcacheCache is ehcache's implementation of the Cache interface:

Modify the mapper.xml file, specify EhcacheCache in the cache, and adjust the cache parameters as required:

<cache type="org.mybatis.caches.ehcache.EhcacheCache" > 
    <property name="timeToIdleSeconds" value="3600"/>
    <property name="timeToLiveSeconds" value="3600"/>
    <!-- 同ehcache参数maxElementsInMemory -->
    <property name="maxEntriesLocalHeap" value="1000"/>
    <!-- 同ehcache参数maxElementsOnDisk -->
    <property name="maxEntriesLocalDisk" value="10000000"/>
    <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>

Application scenario

For query requests with many visits and users do not have high requirements for real-time query results, mybatis secondary cache technology can be used to reduce database access and improve access speed. Business scenarios such as time-consuming statistical analysis SQL, phone bills Query sql etc.

The implementation method is as follows: by setting the refresh interval, mybatis automatically clears the cache at intervals, and sets the cache refresh interval flushInterval according to the frequency of data changes, such as 30 minutes, 60 minutes, 24 hours, etc., according to the needs.

limitation

Mybatis second-level cache is not good for fine-grained data-level caching, such as the following requirements: cache product information, due to the large number of product information query visits, but requiring users to query the latest product information every time, if Using the second-level cache of mybatis can not realize that when a product changes, only the cache information of the product is refreshed without refreshing the information of other products, because the second-level cache area of ​​mybaits is divided by mapper unit, when a product information changes, all All the cache data of product information is cleared. Solving such problems requires targeted caching of data at the business layer according to demand.

Published 202 original articles · praised 37 · 30,000+ views

Guess you like

Origin blog.csdn.net/lovecuidong/article/details/102729464