Mybatis study notes mybatis transactions and caching

The meaning of business

1. What is a transaction?

Multiple operations are performed at the same time, either succeeding or failing at the same time. This is business.
Transactions have four characteristics: consistency, durability, atomicity, and isolation
For example, there is an order business

1.Add a record to the order table
2.Product quantity data update(reduce)
3.....

When multiple tasks are operating at the same time, these tasks can only succeed at the same time, or fail at the same time.

2.Mybatis about transaction management

Transactions in the MyBatis framework are committed manually by default, that is, every time you write a program, you need to call the commit() method to commit the transaction

<transactionManager type="JDBC"></transactionManager>
  ====>Programmers themselves control commits and rollbacks of processing


To set the automatic commit transaction, you can set it through the openSession method, and openSession(true) automatically commits the transaction. The code is as follows: (the policy in the configuration remains unchanged)

public class UserTest {

    private InputStream in = null;
    private SqlSession session = null;
    private UserDao mapper = null;

    @Before  //Pre-notification, executed before method execution
    public void init() throws IOException {
        //Load the main configuration file in order to build the SqlSessionFactory object
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //Create SqlSessionFactory object
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //Create SqlSession object through SqlSessionFactory factory object
        session = factory.openSession(true);
        //Create UserDao interface proxy object through Session
        mapper = session.getMapper(UserDao.class);
    }

    @After  //@After: Post notification, executed after the method is executed.
    public void destory() throws IOException {
        //release resources
        session.close();
        in.close();
    }

    @Test
    public void insertMoreByList(){
        User user1 = new User("a1","male","Beijing");
        User user2 = new User("a2","male","Beijing");
        User user3 = new User("a3","male","Beijing");
        List<User> users = Arrays.asList(user1,user2,user3);

        int result = mapper.insertMoreByList(users);
        //session.commit();
        System.out.println(result);
    }


}

2. What is cache

1. What is cache

  • data stored in memory
  • Store the data frequently used by users in the cache (memory), the user does not need to query the data from the disk (relational database file), but from the cache, thereby improving the query efficiency and solving the performance problem of high-concurrency systems

2. Why use cache

Reduce the number of interactions with the database, reduce system overhead, and improve system efficiency

3. What kind of data can use the cache

  • Data that is frequently queried and infrequently changed

3. Mybatis cache

  • mybatis includes a very powerful query cache feature, which can be very convenient to customize and configure the cache. Caching can greatly improve query efficiency
  • Two levels of cache are defined by default in the mybatis system: the first level cache and the second level cache
    * By default, only the first level cache is enabled (sqlSession level cache)
    *The second-level cache needs to be manually enabled and configured, and a local namespace-level cache is required.

1. Level 1 cache

1. The first level cache is also called the local cache

  • Data queried during the first session with the database is placed in the local cache.
  • If you need to get the same data in the future, go directly to the cache to get it, there is no need to query the database
  • Each SqlSession created will have its own cache

2. Test the L1 cache

public class UserTest {
    private InputStream in = null;
    private SqlSession session = null;
    private UserDao mapper = null;

    /**
     * Test query all methods
     */
    @Test
    public void findById() throws IOException {
        //Load the main configuration file in order to build the SqlSessionFactory object
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //Create SqlSessionFactory object
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //Create SqlSession object through SqlSessionFactory factory object
        session = factory.openSession();
        //Create UserDao interface proxy object through Session
        mapper = session.getMapper(UserDao.class);

        User user1 = mapper.findById(1);
        System.out.println(user1.toString());
        System.out.println("-----------------");
        User user2 = mapper.findById(1);
        System.out.println(user2.toString());
        System.out.println(user1 == user2);
        //release resources
        session.close();
        in.close();
    }
}

3. Cache invalidation

  • sqlSession is different
  • The sqlSession is the same, but the query conditions are different
  • The sqlSession is the same, and the addition, deletion and modification operations are performed between the two queries! (The data in the database has changed, just in case, the cache needs to be cleared and Sqlsession invalidation processing)
  • sqlSession is the same, manually clear the first level cache

1.sqlSession is different


2. The sqlSession is the same, but the query conditions are different


3. The sqlSession is the same, and the addition, deletion and modification operations are performed between the two queries!


4. The same as sqlSession, manually clear the first level cache


2. L2 cache

The second-level cache of MyBatis is very powerful. Unlike the first-level cache, which only exists in the life cycle of SqlSession, it can be understood as existing in the life cycle of SqlSessionFactory.

1. Enable the second level cache in the SqlMapConfig.xml configuration file

<!‐‐ Enable L2 cache ‐‐>
<settings>
    <!--Enable L2 cache-->
    <setting name="cacheEnabled" value="true"/>
</settings>

2. Declare the use of second-level cache in the UserDao.xml configuration file

<!--Use second level cache-->
<cache eviction="FIFO"  #retraction strategy   
        flushInterval="6000" #Refresh interval, how long to clear the cache, the default is not clear, set a millisecond value
        size="512"  #number of references how many elements to cache
        readOnly="true"/>  #read only

3. The specific details of the parameters

eviction (withdrawal strategy)

LRU(least recently used):Remove objects that have not been used for the longest time, this is the default.
FIFO(first in first out):Remove objects in the order in which they entered the cache.
SOFT(soft reference):Remove objects based on garbage collector state and soft reference rules.
WEAK(weak reference):More aggressive removal of objects based on garbage collector state and weak reference rules.

flushinterval (flush interval)

Can be set to any positive integer, and they represent a reasonable time period 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 (number of references)

Can be set to any positive integer, keeping in mind the number of objects cached and the number of memory resources available to the runtime environment. The default value is 1024.

readOnly (read only)

properties can be set to true or false. A read-only cache returns the same instance of the cached object to all callers, so these objects cannot be modified,
    This provides a significant performance advantage.
Read-write caches will return a copy of the cached object through serialization, which is slower but safe, so the default is false. 

4. Use L2 cache on select tag

<select id="findById" parameterType="int" resultType="User" useCache="true" >
    select * from user where id = #{id}
</select>

5. Test method

@Test
public void findById() throws IOException {
    // 1. Load the SqlMapConfig configuration file
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    //2. Create the sqlSessionFactory factory
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    //3.sqlSessionFactory creates sqlSession
    SqlSession sqlSession = factory.openSession();
    SqlSession sqlSession2 = factory.openSession();

    //4. Create UserDao interface proxy object through Session
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    UserDao mapper2 = sqlSession2.getMapper(UserDao.class);

    User user1 = mapper.findById(1);
    System.out.println(user1.toString());
    // Put the data of its first level cache into the second level cache and clear the first level cache
    sqlSession.commit();

    System.out.println("-----------------");
    User user2 = mapper2.findById(1);
    System.out.println(user2.toString());
    System.out.println(user1 == user2);
    // Put the data of its first level cache into the second level cache and clear the first level cache
    sqlSession2.commit();



    //7. Close resources
    sqlSession.close();
    resourceAsStream.close();
}

6. It is found that the address values ​​of the two objects are different, but the query of the SQL statement is only sent once. The data stored in the second-level cache is not the object.
7. The session.commit() or session.close() method must be called for the second-level cache to take effect.
Because our data is stored in the first-level cache by default, the data will only be written to the second-level cache when the current session is closed.

Tags: Mybatis Cache

Posted by Brakanjan on Sun, 18 Sep 2022 02:33:56 +0930