Mybatis cache structure

Time:2020-8-5

When users access the cache a little, we can put the results of the next query in the container.

Level 1 query cache

The first level cache is based onOf the instance object of the same sqlsession class。 The data regions of instance objects of different sqlsession classes are not affected by each other. Mybatis supports level 1 caching by default.

First level cache test example

For example, the same sqlid is used to query the sqlid for two times

@Test  
public void testFindCustomerCache1() throws Exception{  
    SqlSession sqlSession=dataConnection.getSqlSession();  
  
    //Call the method of usermapper  
    User user1=  
            sqlSession.selectOne("test.findUserById",1);  
    System.out.println ("user name: + user1. Getusername());  
  
    User user2=  
            sqlSession.selectOne("test.findUserById",1);  
    System.out.println ("user name: + user2. Getusername());  
    sqlSession.close();  
}

To view the run results:
Mybatis cache structure
It can be seen from the figure that when the user information with ID 1 is queried for the first time, the database connection is opened and the database connection is established. Then, the SQL statement is precompiled and the input parameters are set. Finally, the information of the user with ID 1 is queried from the database. However, when querying the user with ID 1 for the second time, it is found that there is no log output, and only the information when the data is retrieved is printed. This shows that the second data is not retrieved from the database, but from the first level cache.

Before querying the information of the user with ID 1 for the second time, modify an attribute of the user:

@Test  
public void testFindCustomerCache2() throws Exception{  
    SqlSession sqlSession=dataConnection.getSqlSession();  
  
    //Call the method of usermapper  
  User user1=  
            sqlSession.selectOne("test.findUserById",1);  
    System.out.println ("user name: + user1. Getusername());  
  
    String username "Zhangge";  
    user1.setUsername(username);  
    System.out.println ("modify the user name as" + username) ";  
    sqlSession.update("test" +  
            ".updateUserName",user1);  
    sqlSession.commit();  
  
    User user2=  
            sqlSession.selectOne("test.findUserById",1);  
    System.out.println ("user name: + user2. Getusername());  
    sqlSession.close();  
}

Test results:
Mybatis cache structure
It can be seen that before querying the cache data, the sqlsession class will empty its first level cache if there are operations to change the data, such as adding, deleting, and modifying.

Level 2 query cache

If the first level cache cannot be used, the second level cache can be used.
The second level cache is mapper level cache. Instance objects of multiple sqlsession classes operate SQL statements in the same mapper configuration file. Instance objects of multiple sqlsession classes can share the second level cache. The second level cache is based on the namespace, and the operations under different namespaces do not affect each other.

Test example of L2 cache

First, two steps are required to enable the level 2 cache. The first step is to add the following in the global configuration file of mybatis

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

Then, you need to open the level 2 cache mapper.xml Enable secondary cache in file:

<cache/>

Java entity class serialization interface of customer information to be queried:

package cn.com.mybatis.po;  
  
import java.io.Serializable;  
import java.util.List;  
 
//The serializable interface has no methods or fields and is only used to identify serializable semantics
public class Customer implements Serializable{  
    private int cus_id;  
    private String username;  
    private String acno;  
    private String gender;  
    private String phone;  
    private List<Batch> batchList;  
    //Set and get methods omitted
}

The reason for the customer class to implement the serialization interface is that in order to extract the cached data and perform the deserialization operation, the secondary cache data storage media are various (such as memory, hard disk, server), which are not necessarily in memory.

@Test  
public void testFindCustomerOnMapper1() throws Exception{  
      SqlSession sqlSession =  
            dataConnection.getSqlSession();  
    //Get mapper proxy  
  CustomerMapper customerMapper1 = sqlSession.getMapper(CustomerMapper.class);  
    //Query method for executing mapper proxy object  
  Customer customer1 =  
            customerMapper1.findCustomerById(1);  
    System.out.println ("user name: + customer1. Getusername() +" | "+" card No.: + customer1. Getacno());  
  
    //Get mapper proxy  
  CustomerMapper customerMapper2 = sqlSession.getMapper(CustomerMapper.class);  
    //Query method for executing mapper proxy object  
  Customer customer2 =  
            customerMapper2.findCustomerById(1);  
    System.out.println ("user name: + customer2. Getusername() +" | "+" card No.: + customer2. Getacno());  
  
}

Running test results:
Mybatis cache structure

Verify L2 cache emptying

When a mapper performs the operations of adding, deleting, modifying and querying, the secondary cache will be cleared to prevent dirty reading of data.

@Test  
public void testFindCustomerOnMapper2() throws Exception{  
    SqlSession sqlSession =  
            dataConnection.getSqlSession();  
    //Get mapper proxy  
  CustomerMapper customerMapper1 = sqlSession.getMapper(CustomerMapper.class);  
    //Query method for executing mapper proxy object  
  Customer customer1 =  
            customerMapper1.findCustomerById(1);  
    System.out.println ("user name: + customer1. Getusername() +" | "+" card No.: + customer1. Getacno());  
  
    CustomerMapper customerMapper3 = sqlSession.getMapper(CustomerMapper.class);  
    String AcNo = "3228286666666";  
    customer1.setAcno(AcNo);  
    customerMapper3.UpdateCustomerAcNo(customer1);  
    System.out.println (the card number of "modified user name" + customer1. Getusername() + "|" + "is" + customer1. Getacno());  
    sqlSession.commit();  
  
  
    //Get mapper proxy  
  CustomerMapper customerMapper2 = sqlSession.getMapper(CustomerMapper.class);  
    //Query method for executing mapper proxy object  
  Customer customer2 =  
            customerMapper2.findCustomerById(1);  
    System.out.println ("user name: + customer2. Getusername() +" | "+" card No.: + customer2. Getacno());  
    sqlSession.close();  
}

Running test results:
Mybatis cache structure

It should be noted that when using level 2 cache, it is necessary to ensure that the data under the mapper will not be stored in other databases Mapper.xml There is a cache in the file. For example, in the UserMapper.xml There are many operations on the user table in the xxxMapper.xml There are also operations on the user single table. This will cause the user’s cache data to be inconsistent under the two namespace.
If this situation cannot be avoided and secondary cache needs to be used, it is recommended to use interceptor to determine which tables are involved in the executed SQL, and then clear the cache of related tables.

Recommended Today

CSS functions (2) you don’t know attr ()

The attribute function attr() is used to obtain the attribute values in HTML elements and is used in styles. However, it can only be applied to pseudo elements in CSS elements for the time being. example Implement a tooltip <!DOCTYPE html> <html lang=”en”> <head> <meta charset=”UTF-8″ /> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″ /> < title > […]