Mybatis series

1. The most detailed introduction and basic use of Mybatis in the whole network

2, the most complete network MyBatis based on XML use series 1: global configuration details

3, the most complete network MyBatis based on XML using series 2: parameters, return results processing

4. MyBatis is based on XML using series 3: dynamic Sql

5, the most complete network MyBatis based on XML using series 4: cache

Why cache

When user query the same data many times, if you don’t need to cache, so every time need to access the database, so as to increase the pressure of the database, when using the cache, the first time the data from the database query, query the data saved in the cache, when a user queries the same data again, don’t have direct access to the database query, Query directly from the cache. This reduces the loss of network connections and database queries, improves the efficiency of code queries, and reduces system performance problems caused by high concurrent access.

In summary: to query some data that does not change often, the use of caching can improve the query efficiency and reduce the occurrence of concurrency problems.

Mybatis cache is mainly divided into level 1 cache and level 2 cache

Level 1 cache

Mybatis level 1 cache is mainly SqlSession level, the default is active.

The basic concept

Mybatis will store the result set in the cache and return the result if the SQL statement is executed for the second time until the NTH time. The SqlSession will then query the data currently cached for the first time and return it directly without requesting a database query again.

Basic authentication

@Test
public void test01(a){
     SqlSession sqlSession=sqlSessionFactory.openSession();
     try{
         EmpMapper mapper=sqlSession.getMapper(EmpMapper.class);
         List<Emp> list=mapper.selectAllEmp();
         for(Emp emp:list){
             System.out.println(emp);
        }
         System.out.println("= = = = = = = = = = = = =");
         List<Emp> list2=mapper.selectAllEmp();
         for(Emp emp:list2){ System.out.println(emp); }}catch(Exception e){
         e.printStackTrace();
    }finally{
         sqlSession.close();
    }
Copy the code

Analysis: Although we queried twice in the above code, only one database operation was performed. This is where Mybatis provides the first level cache. Because of the existence of the level-1 cache, the second query for the record whose ID is 1 does not issue a SQL statement to query the data from the database, but from the level-1 cache.

Level 1 cache invalidation

Multiple SQLSessions are enabled, and the cache is invalid. Procedure

Level 1 cache is the sqlSession level cache. If only multiple SQLSessions are enabled in an application, the cache will be invalidated

@Test
public void test02(a) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    List<Emp> list = mapper.selectAllEmp();
    for (Emp emp : list) {
        System.out.println(emp);
    }
    System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
    List<Emp> list2 = mapper2.selectAllEmp();
    for (Emp emp : list2) {
        System.out.println(emp);
    }
    sqlSession.close();
    sqlSession2.close();
}
Copy the code

Parameter inconsistent, cache invalid

Data was modified during sending and the cache was invalid

@Test
public void test03(a) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp empByEmpno = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno);
    System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    empByEmpno.setEname("zhangsan");
    int i = mapper.updateEmp(empByEmpno);
    System.out.println(i);
    System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno1);
    sqlSession.close();
}
Copy the code

Between the two queries, the cache was manually cleared, and the cache became invalid

@Test
public void test03(a) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp empByEmpno = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno);
    System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    System.out.println("Manually clear cache");
    sqlSession.clearCache();
    System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
    Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno1);
    sqlSession.close();
}
Copy the code

conclusion

Features:

  • 1. LocalCacheScope =STATEMENT Is enabled by default. You can also disable level-1 cache
  • 2. Scope: is based on sqlSession (default), a database operation session.
  • 3. The default implementation of caching class PerpetualCache, which uses Map for storage
  • 4. After the query is complete, it is stored
  • 5. Obtain * key from level-2 cache and then from level-2 cache ==> sqlid+ SQL

Failure condition:

  • 1. Different SQLSessions invalidate level 1 cache
  • 2. Use the same SqlSession but different query statements
  • 3. In the same SqlSession, the query statement is the same
  • 4. The same SqlSession query statement is used to manually clear the cache

The second level cache

Level 2 cache is the namespace level cache, which is lower than level 1 cache. Generally, Mybatis does not enable level 2 cache by default.

If you want to enable level 2 caching, you need to implement two conditions

  • Entity classes must be serialized
  • Configure the cache label in the XML configuration file

Basic implementation

  • 1. Add the following configuration to the global configuration file:
<settings>
<! Since cacheEnabled is set to true by default, this step can be omitted. If the value is true, level 2 cache is enabled. False indicates that level-2 caching is disabled. -->
    <setting name="cacheEnabled" value="true"/>
</settings>
Copy the code
  • 2. Configure the empmapper. XML mapping
<! -- Enable level 2 cache for current mapping files -->
<cache></cache>
Copy the code
  • 3. Modifying an entity class must implement the Serializable interface

  • 4. Test implementation

@Test
public void test04(a) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
    Emp empByEmpno = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno);
    sqlSession.close(); 
    Emp empByEmpno1 = mapper2.findEmpByEmpno(1111);
    System.out.println(empByEmpno1);
    sqlSession2.close();
}
Copy the code

Cache tag attributes

  • Eviction: cache reclamation policy, default is LRU

    • LRU: Least recently used. Remove 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: removes objects based on garbage collector status and SOFT reference rules

    • WEAK: WEAK references, which more aggressively remove objects based on garbage collector state and WEAK reference rules

  • FlushInternal: flushinterval, in milliseconds

    The default is not set, that is, there is no refresh interval, and the cache is only refreshed when the statement is called

  • Size: indicates the number of references, which is a positive integer

    Represents the maximum number of objects that can be stored in the cache

  • Readonly: read-only, true/false

    • True: read-only cache, which returns the same instance of the cache object to all calls, and therefore cannot be modified.

    • False: read and write cache, which returns a copy of the cache object (serialization implementation). This method is safer. Default value

@Test
public void test05(a) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
    Emp empByEmpno = mapper.findEmpByEmpno(1111);
    System.out.println(empByEmpno);
    sqlSession.close(); 
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
    Emp empByEmpno2 = mapper2.findEmpByEmpno(1111);
    System.out.println(empByEmpno2);
    Emp empByEmpno3 = mapper2.findEmpByEmpno(1111);
    System.out.println(empByEmpno3); 
    Emp empByEmpno4 = mapper2.findEmpByEmpno(7369);
    System.out.println(empByEmpno4);
    Emp empByEmpno5 = mapper2.findEmpByEmpno(7369);
    System.out.println(empByEmpno5);
    sqlSession2.close();
}
Copy the code

conclusion

Features:

  • 1. This function is enabled by default
  • 2. Scope: Based on global scope, application level.
  • 3. The default implementation of the cache class PerpetualCache is PerpetualCache, which is stored using a Map, but the level 2 cache packets a layer of maps based on the different mapper namespace
  • 4. Transaction commit time (sqlSession closed)
  • 5. Obtain * from level-2 cache and then level-2 cache

Implementation:

  • 2. Add the mapping file that needs to be used for level-2 cache based on Mapper mapping file for cache and Mapper mapping file for namespace storage

  • 3. Implement serialization interface implements Serializable in javaBean that needs to use level 2 cache

    • If the configuration is successful, the cache hit ratio will be the same as sqlId: the number of times taken out of the cache/the total number of times queried

Failure:

  • 1. If a namespace is added, deleted, or modified, level-2 cache becomes invalid

    If you don’t want to invalidate, set the SQL flushCache to false, but be careful because it can cause dirty reads unless you can guarantee that the data in the query will never be added or deleted

  • UseCache =”false”

  • 3. If you want the namespace of other mapper files to be added, deleted, and cleared, you can set this parameter:

    <cache-ref namespace="com.mybatis.mapper.DeptMapper"/>