Detailed explanation of Mybatis caching mechanism (first level cache + second level cache)

What is the first level cache

MyBatis includes a very powerful query caching feature , it can be very easily configured and customized. Many improvements to the cache implementation in MyBatis 3 have been implemented, making it more powerful and easy to configure. Mybatis will only turn on the first level cache by default, which is the local session cache .

First of all, we need to know what is the query cache? What is the role of query cache?

Function: Mybatis provides query cache to reduce data pressure and improve database performance.

As shown in the figure below, each session will have its own cache. This cache is partial, which is the so-called first-level cache :


Under what circumstances will hit the first level cache

  1. Same sql and parameters
  2. Must be in a session Session which
  3. It must be executed in the same manner
  4. Must be the same namespace (same namespace -> same mapper file)
  5. Cannot execute clearCache before query
  6. Intermediate can not perform any Update, Delete, INSERT (all data will be empty in SqlSession)

Detailed explanation of Mybatis's caching mechanism

The first level cache is the SqlSession level cache. We all know that the sqlSession object needs to be constructed when operating the database, and there is a data structure (HashMap) in the sqlSession object for storing cached data.

As shown below:

Detailed explanation of Mybatis's caching mechanism

From the figure, we can see that the first level cache area is divided according to SqlSession. Each query will first find the data from the cache area, if not found, it will query the data from the database, and then write the queried data into the first-level cache. Mybatis internal storage cache uses a HashMap object , the key is hashCode + sqlId + sql statement. The value value is the java object generated from the query mapping. In order to ensure that the data in the cache is definitely accurate data to avoid dirty reads, every time we modify the data (add, delete, and modify operations), we will execute a commit operation to clear the cache area.


Insert picture description here
Insert picture description here

SqlSession and Executor are both interfaces, and the implementation is DefaultSqlSession and CacheExecutor

  • Client is equivalent to test method Test1
  • User@Proxy dynamic proxy (equivalent to a pseudo-emperor, just responsible for forwarding) == UserMapper (proxy object) in the code is actually useless
  • The Executor interface is to run errands to get data in the database
  • SqlSession is the interface
  • The first level cache is implemented through CacheExecutor

Detailed explanation of the underlying implementation! !

Insert picture description here
Insert picture description here

Enter the breakpoint in the selectById method and the getObject (Object key) in the underlying implementation class PrepetualCache.
You can see that by observing the debug stack information

  1. The green box in the picture above is the implementation of the dynamic agent. It doesn’t make any sense. It’s just a transfer, so ignore this part.
  2. Going up, we are querying selectOne, but we will still query SelectList and then convert through DefaultSqlSession.

What is really related to the cache is the implementation of these lines

What is really related to the cache is the implementation of these lines

The process is as follows
Insert picture description here
Insert picture description here

This step:

  • As can be seen in the cache key is the inclusion of methods and namespace and session these will have to do the same as a cache hit
  • It encapsulates the unique key of the cache

Insert picture description here

  • There is a CacheExecutor in DefaultSqlSession
  • There is a Simpleexexutor in CacheExecutor
  • There is one in Simpleexexutor called LocalCache (PerpetualCache type)
  • LocalCache is the real place to store the cache
  • There is a cache in LocalCache (hashmap <Object, Object> type)

Insert picture description here
Insert picture description here
Insert picture description here

Insert picture description here
Insert picture description here

We will get through the first level cache! ! !

Insert picture description here

PUT process of the first level cache

The first few processes are the same as the above picture.
Insert picture description here
The life cycle of Cache is the same as SqlSession.

Will there be data inconsistencies?

Not because the database itself has a transaction isolation level and the default is repeatable read. That is to say, the data read by any transaction in it is consistent, so there is no problem of data inconsistency


Mybatis secondary cache

Insert picture description here

The second-level cache usage conditions must be configured with namespace annotation
put. When the second-level cache, this session must be closed to put (because cross-transaction reading otherwise dirty read problems will occur)

Under what circumstances will hit the first level cache

  1. Same sql and parameters
  2. Must be in a session Session which
  3. It must be executed in the same manner
  4. Must be the same namespace (same namespace -> same mapper file)
  5. Cannot execute clearCache before query
  6. Intermediate can not perform any Update, Delete, INSERT (all data will be empty in SqlSession)
  7. Conditions secondary cache must be configured Cachenamespace annotations
  8. When putting the second-level cache, this session must be closed to put (because cross-transaction reading otherwise there will be dirty reading problems)

The second-level cache is a mapper-level cache. Multiple SqlSessions operate on the same Mapper's SQL statement. Multiple SqlSessions can share the second-level cache. The second-level cache can span across SqlSessions.

Diagram:

Detailed explanation of Mybatis's caching mechanism

The second-level cache area is divided according to the namespace of the mapper. ** The mapper query data of the same namespace is placed in the same area. ** If the mapper proxy method is used, the namespace of each mapper is different, and it can be understood as the second-level cache area. It is divided according to the mapper, that is, according to the namespace. If the namespace of the two mapper files is the same, then different SqlSessions can share a mapper cache.

Diagram:

Detailed explanation of Mybatis's caching mechanism

By default, the second level cache is not enabled, except for the local session cache . In the first-level cache, we also introduced that the first-level cache between different SqlSessions is not shared, so if we use two SqlSessions to query the same data, both will send SQL to the database.

After the second-level cache is turned on, the data between SqlSessions can be shared through the second-level cache. Like the first-level cache, the second-level cache area will be cleared after operations such as insert, update, and delete are executed and commit is submitted. When the first-level cache and the second-level cache exist at the same time, the second-level cache will be accessed first, and then the respective first-level cache will be accessed. If there is no required data, SQL will be sent to the database for query.

Guess you like

Origin blog.csdn.net/weixin_44284160/article/details/109271495