编程知识 cdmana.com

Do you know something about mybatis caching?

The way cache is implemented

  • First level cache

  • Second level cache

Case practice

1. First level cache

be based on PerpetualCache Of HashMap Local cache (mybatis Internal implementation cache Interface ), Its storage scope is Session, When Session flush or close after , The Session All in Cache Will be emptied ;

2. Second level cache

The first level cache has the same mechanism , Default is also used PerpetualCache Of HashMap Storage , The difference is that the storage scope is Mapper(Namespace), And you can customize the storage source , Such as Ehcache;

For cache data update mechanism , When a scope ( First level cache Session/ Second level cache Namespaces) It's going on C/R/U/D After the operation , By default, all select Cache in will be clear.

If the second cache is on , First, query the data from the L2 cache , If there is a L2 cache, the data is retrieved from the L2 cache , If the L2 cache doesn't have , Find whether there is cache data from the first level cache , If the first level cache does not , Query the database .

3. L2 cache limitations

mybatis Second level cache is not good for fine-grained data level cache , A cache that caches more data at the same time , For example, the following requirements : Cache product information , Due to the large number of commodity information query visits , But users are required to query the latest product information every time , If you use mybatis When a product changes, it can only refresh the cache information of the product without refreshing the information of other products , because mybaits The second level cache area of the mapper Divide into units , When a product information changes, the cache data of all product information will be cleared

4. First level cache ( Default on )

Mybatis First level cache is provided by default , The cache range is a sqlSession. In the same SqlSession in , Perform the same... Twice sql Inquire about , The second time no more queries from the database .

principle : The first level cache uses Hashmap Storage ,mybatis When executing a query , Query from cache , If there is no query from the database in the cache . If it's time to SqlSession perform clearCache() Submit or add delete modify operation , Clear cache .

Default exists , Understand the observation

a. Cache presence (session Not submitted )

@Test 

public void test01() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    accountDao.queryAccountById(1);  

} 

The log only prints one sql

 About  Mybatis  The cache thing , You know what? ?

b. Refresh cache

Session The cache data is refreshed at the time of commit

@Test 
public void test02() { 
    SqlSession sqlSession=sqlSessionFactory.openSession();  
    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  
    Account account=accountDao.queryAccountById(1); 
    System.out.println(account); 
    sqlSession.clearCache(); 
    accountDao.queryAccountById(1);  
} 

effect :

 About  Mybatis  The cache thing , You know what? ?

5. Second level cache

The first level cache is in the same sqlSession in , The L2 cache is in the same namespace in , So the same namespace Different sqlsession You can use L2 caching .

Use scenarios

  • High frequency of query , Second level cache is recommended for data with low change frequency .
  • For the query request with more access and the user's demand for real-time query results is not high , You can use mybatis Second level cache technology reduces database access , Improve access speed , Business scenarios such as : Time consuming statistical analysis sql、 Phone bill inquiry sql etc. .

Global file configuration (mybatis.xml)

<setting name="cacheEnabled" value="true"/> 
Mapper.xml  Add  : Open the  mapper  Second level cache of  

<!--  Turn on the  mapper  Second level cache of  --> 

<cache/>

cache Common attributes of label

<cache  

eviction="FIFO" <!-- The recovery strategy is FIFO --> 

flushInterval="60000" <!-- Auto refresh time  60s--> 

size="512" <!-- Maximum cache  512  References --> 

readOnly="true"/> <!-- read-only --> 

explain :

  1. Map all in statement file select Statement will be cached .
  2. Map all in statement file insert,update and delete Statement flushes the cache .
  3. The cache will use Least Recently Used(LRU, Least recently used ) Algorithm to recover .
  4. The cache will refresh according to the specified time interval .
  5. The cache will store 1024 Objects

PO Objects must support serialization

public class User implements Serializable { 

} 

close Mapper The following is specific statement The cache of

Use useCache: The default is true

<select id="findUserByid" parameterType="int" resultType="User"  

useCache="false"> 

    SELECT * FROM user WHERE id=#{id} 

</select> 

Refresh L2 cache

operation CUD Of statement When , Will force a refresh of the L2 cache Default flushCache="true" , If you want to turn off, set it to flushCache="false" that will do , It is not recommended to turn off refresh , Because of the operation update, delete and modify , It's easy to get dirty data after closing .

L2 cache test :

@Test 

public void test03() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    sqlSession.close(); 

    SqlSession sqlSession2=sqlSessionFactory.openSession(); 

    AccountDao accountDao2=sqlSession2.getMapper(AccountDao.class);  

    accountDao2.queryAccountById(1); 

    sqlSession.close(); 

} 

effect :

 About  Mybatis  The cache thing , You know what? ?

Expand

Distributed cache ehcache

If there are multiple servers , Don't use distributed caching , The cached data is stored separately in each server , Inconvenient for system development . So we need to use distributed cache to manage cache data centrally . So you can use ehcache memcached redis

mybatis In itself, distributed caching cannot be implemented , So we need to integrate with distributed caching framework . EhCache It's pure. Java In process caching framework for , With fast 、 Characteristics such as ability ;Ehcache It's a wide range of Open source used Java Distributed cache . Mainly for general purpose cache ,Java EE And lightweight containers . It has memory and disk storage , Cache loader , Cache extension , Cache exception handler , One gzip cache servlet filter , Support REST and SOAP api Other characteristics .

Jar rely on

<dependency> 

    <groupId>net.sf.ehcache</groupId> 

    <artifactId>ehcache-core</artifactId> 

    <version>2.4.4</version> 

</dependency> 

<dependency> 

    <groupId>org.mybatis.caches</groupId> 

    <artifactId>mybatis-ehcache</artifactId> 

    <version>1.0.3</version> 

</dependency> 

Cache interface configuration

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

stay src Next Join in ehcache.xml( It's not necessary. There's no default configuration )

<?xml version="1.0" encoding="UTF-8"?> 

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd"> 

<!-- 

name:Cache  Unique identification of  

maxElementsInMemory: Maximum number of cached objects in memory  

maxElementsOnDisk: Maximum number of cache objects on disk , if  0  Infinity  

eternal:Element  Whether it will never expire , If  true, The cached data is always valid , If  false 

 Then according to  timeToIdleSeconds,timeToLiveSeconds  Judge  

overflowToDisk: Configure this property , When in memory  Element  The number of  maxElementsInMemory  when , 

Ehcache  will  Element  Write to disk  

timeToIdleSeconds: Set up  Element  Allowed idle time before failure . Only when the  element  It's not permanent  

 When using , Optional attribute , The default value is  0, That is to say, the idle time is infinite  

timeToLiveSeconds: Set up  Element  Allow survival time before failure . The maximum time is between creation time and expiration time  

 Between time . Only when the  element  Use when it is not permanent , The default is  0., That is to say  element  The time to live is infinite  

 Big  

diskPersistent: Whether to cache virtual machine restart data  

diskExpiryThreadIntervalSeconds: Disk failure thread run time interval , The default is  120  second  

diskSpoolBufferSizeMB: This parameter setting  DiskStore( Disk caching ) Cache size for . The default is  

30MB. Every  Cache  Should have its own buffer  

memoryStoreEvictionPolicy: When reach  maxElementsInMemory  When the limit ,Ehcache  Will be based on  

 The specified strategy to clean up the memory . The default policy is  LRU( Recently at least use ). You can set to  FIFO( First of all  

 Out ) or  LFU( Use fewer ) 

--> 

<defaultCache overflowToDisk="true" eternal="false"/> 

<diskStore path="D:/cache" /> 

<!-- 

<cache name="sxtcache" overflowToDisk="true" eternal="false" 

timeToIdleSeconds="300" timeToLiveSeconds="600" maxElementsInMemory="1000" 

maxElementsOnDisk="10" diskPersistent="true"  

diskExpiryThreadIntervalSeconds="300" 

diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="LRU" /> 

--> 

test :

@Test 

public void test04() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    sqlSession.close(); 

    SqlSession sqlSession2=sqlSessionFactory.openSession(); 

    AccountDao accountDao2=sqlSession2.getMapper(AccountDao.class);  

    accountDao2.queryAccountById(1); 

    sqlSession.close(); 

} 

effect :
Cache Hit Ratio [com.xxx.dao.AccountDao]:0.5

版权声明
本文为[osc_ wuji6g86]所创,转载请带上原文链接,感谢
https://cdmana.com/2020/12/20201224130113621U.html

Scroll to Top