Believe me, wechat search “Java fish boy” can really be stronger!!

(a) What is the role of cache

In a Web system, the most important operation is to query data in a database. But sometimes the frequency of data query is very high, which is very costly to the database resources, often lead to the database query efficiency is very low, affecting the customer’s operation experience. So we can put some data that doesn’t change much and is frequently accessed in a cache container, and the user gets the results from the cache container the next time they query.

(2) Cache structure of Mybatis

Mybatis system defines two levels of cache by default: level 1 cache and level 2 cache:

Mybatis Level 1 cache is a SqlSession level, SqlSession can only access its level 1 cache data

Level 2 cache is cross-SQLSession and mapper level cache. For MAPper level cache, different SQLsessions can be shared.

Mybatis enables level-1 Cache by default. In order to enhance scalability, Mybatis defines Cache interface Cache. Level-2 Cache can be customized by Cache.

(3) Level 1 cache

Mybatis level 1 cache is a SqlSession level cache. The cache is executed according to the following rules:

The results of all select statements in the mapping statement file will be cached.

2. All INSERT, UPDATE, and DELETE statements in the mapping statement file flush the cache.

3. By default, the Least Recently Used algorithm (LRU) is Used to clear unwanted caches.

4. The cache does not flush regularly (that is, there are no flush intervals).

5. The cache holds 1024 references to lists or objects (whichever is returned by the query method).

6. Caches are treated as read/write caches, which means that retrieved objects are not shared and can be safely modified by callers without interfering with potential changes made by other callers or threads.

Next, simulate the execution of level 1 cache by code, using the code is the simplest user class, first step in mybatis-config enable log:

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
Copy the code

Write the test code to query the second time under the same query conditions:

@Test
public void testSelect(a){
    / / get the SqlSession
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    / / Sql execution
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user=mapper.getUserById(4);
    System.out.println(user);
    // Query the second time with the same condition
    User user2=mapper.getUserById(4);
    System.out.println(user2);
    sqlSession.close();
}
Copy the code

Observations:First, this code is in a SqlSession, so the default is to enable level 1 caching, as shown in the result, the first query is to go to the database, the second query does not need to look up the database. Satisfies the first rule:

The results of all SELECT statements in the mapping statement file will be cached.Copy the code

Insert data into table before second query:

@Test
public void testSelect2(a){
    / / get the SqlSession
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    / / Sql execution
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user=mapper.getUserById(4);
    System.out.println(user);
    // Insert data before the second query
    User user1=new User(5."java");
    mapper.insertIntoUser(user1);
    // Query the second time with the same condition
    User user2=mapper.getUserById(4);
    System.out.println(user2);
    sqlSession.close();
}
Copy the code

Observations:Select * from table_name where table_name = ‘1’; select * from table_name where table_name = ‘1’; select * from table_name where table_name = ‘1’;

All INSERT, UPDATE, and DELETE statements in the mapping statement file flush the cache.Copy the code

You can also flush the cache manually using code:

sqlSession.clearCache();
Copy the code

(4) Two-level cache

Level 2 cache is more scoped than level 1 cache. Level 2 cache is mapper-level cache, which you can also interpret as a namespace cache.

To enable caching in Mybatis, you must first enable cacheEnabled in your Settings

This parameter defaults to true, so it can be written unexplicitly.

2. Use level 2 caching in mapper.xml

<cache/>
Copy the code

You can also use useCache to disable caching for a specific query:

<select id="getUserById" resultMap="UserMap" parameterType="int" useCache="false">
    select id,name from user where id=#{id};
</select>
Copy the code

The cache label can be modified by configuration:

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

Focus on eviction strategies:

LRU – Least recently used: Removes the object that has not been used for the longest time.

FIFO – First in, first out: Objects are removed in the order in which they enter the cache.

SOFT – SOFT reference: Objects are removed based on garbage collector status and SOFT reference rules.

WEAK – WEAK references: Objects are removed more aggressively based on garbage collector state and WEAK reference rules.

The default cleanup strategy is LRU.

The other properties are configured as follows:

The flushInterval property can be set to any positive integer, and the value should be a reasonable amount of time in milliseconds. The default is no, that is, there is no refresh interval, and the cache is flushed only when the statement is called.

The size attribute can be set to any positive integer, taking into account the size of the object to be cached and the memory resources available in the runtime environment. The default value is 1024.

The readOnly property can be set to true or false. A read-only cache returns the same instance of the cache object to all callers. Therefore, these objects cannot be modified. This provides a significant performance boost. A read-write cache returns (through serialization) a copy of the cached object. It’s slower, but safer, so the default is false.