编程知识 cdmana.com

Do you know something about mybatis caching?

About Mybatis The cache thing , You know what? ?

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 ;

  1. 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 .

  1.   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

  1. 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

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 :

  1. 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 :

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

版权声明
本文为[HUIYL1]所创,转载请带上原文链接,感谢

Scroll to Top