mybatis caching mechanism
1.1. L1 cache
- mybatis's L1 cache is enabled by default
- When the parameters are exactly the same as SQL, use * * the same SqlSession * * object to call a Mapper (that is, dao layer) method, and often execute SQL only once, because MyBatis will put it in the cache after the first query using SelSession. When querying later, if there is no statement to refresh and the cache does not timeout, SqlSession will fetch the currently cached data and will not send SQL to the database again.
1.1.1 L1 cache test
1.1.1.1 do not close Sqlsession object
/** * The first level cache test is based on the sqlsession cache, which comes with mybatis * Test method: when querying, do not close the sqlsession. When querying the same statement again, * Then, sql session will not submit sql statements and will extract data from the cache */ @Test public void cache(){ IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class); System.out.println("---------------First query---------------"); List<Student> studentList = studentDao.findAll(); studentList.forEach(System.out::println); System.out.println("---------------Second query---------------"); studentList = studentDao.findAll(); studentList.forEach(System.out::println); }
-
Operation results:
- Sqlsession is not closed, and the same sql statement will be submitted only once
- The first query sends the SQL statement and returns the result;
- The second query did not send an SQL statement, and the results were obtained directly from memory.
1.1.1.2 close Sqlsession object
/** * The first level cache test is based on the sqlsession cache, which comes with mybatis * Test method: when querying, close sqlsession and query the same statement again * */ @Test public void cache1(){ IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class); System.out.println("---------------First query---------------"); List<Student> studentList = studentDao.findAll(); studentList.forEach(System.out::println); //Manual shutdown sqlSession.close(); //Then create a new sqlsession SqlSession sqlSession1 = sessionFactory.openSession(); studentDao = sqlSession1.getMapper(IStudentDao.class); System.out.println("---------------Second query---------------"); studentList = studentDao.findAll(); studentList.forEach(System.out::println); }
- Operation results
- The SQL statement was executed twice
1.1.1.3 insert, update and delete
For the same SqlSession object, inserting, updating and deleting these DML operations will clear the cache, which is equivalent to adding f lushCache = "true" in IStudent.xml
/** * The first level cache test is based on the sqlsession cache, which comes with mybatis * Test method: add, delete and update these DML operations */ @Test public void cache1_1(){ IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class); List<Student> studentList = studentDao.findAll(); studentList.forEach(System.out::println); Student student = new Student(); student.setId(5); student.setName("lan"); student.setAge(18); student.setPhone(12313); studentDao.saveStu(student); sqlSession.commit(); studentList = studentDao.findAll(); studentList.forEach(System.out::println); }
- Operation results
1.1.2 L1 cache summary
- In the same SqlSession, Mybatis will generate cached key values for the executed methods and parameters through the algorithm, and store the key values and results in a Map. If the subsequent key values are the same, Mybatis will directly obtain data from the Map;
- Caches between different sqlsessions are isolated from each other;
- With a SqlSession, the cache can be emptied before query through configuration;
- When the L1 cache executes the commit, close, UPDATE, INSERT, DELETE statements and other operations, the current L1 cache will be emptied
1.2 L2 cache
- The L2 cache exists in the SqlSessionFactory lifecycle.
- After two session s are established, the second level cache will not execute the same select statement in the database after executing the same select statement, and the content will still be read from the cache.
1.2.1 configure L2 cache
1.2.1.1 global switch
- In mybatis, the L2 cache has global switches and sub switches. The global switches are configured in mybatis-config.xml as follows:
<settings> <!--Set global L2 cache--> <setting name="cacheEnabled" value="true"/> </settings>
1.2.1.2 sub switch
- On / off means that the L2 cache is turned on or off in * Mapper.xml. It is not turned on by default
1.2.1.3 implementing serialization in entity classes
@Data /*You can use the setter getter method*/ public class Student implements Serializable { private static final long serialVersionUID = -3651117125904238574L; Integer id; String name; Integer phone; String stu_id; Integer age; }
1.2.1.4 Mapper interface mapping file configuration L2 cache
<!--Mapper(that is Dao)Interface mapping profile--> <mapper namespace="cn.glxs.dao.IStudentDao"> <!--L2 cache configuration: eviction Recovery strategy, flushInterval Refresh interval, size Number of references, readOnly read-only--> <cache eviction="FIFO" flushInterval="60000" size="1024" readOnly="false"/> <select id="findAll" resultType="cn.glxs.domain.Student" > select * from stu </select> </mapper>
1.2.1.5 testing
//L2 cache @Test public void cache2() { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); IStudentDao studentDao1 = sqlSession1.getMapper(IStudentDao.class); IStudentDao studentDao2 = sqlSession2.getMapper(IStudentDao.class); System.out.println("---------------First query---------------"); List<Student> studentList = studentDao1.findAll(); studentList.forEach(System.out::println); //You need to manually close the first sqlsession, otherwise the secondary cache will not work, and the secondary select statement will still be executed and sent to the database sqlSession1.close(); sqlSession2 = sqlSessionFactory.openSession(); studentDao2 = sqlSession2.getMapper(IStudentDao.class); System.out.println("---------------Second query---------------"); studentList = studentDao2.findAll(); studentList.forEach(System.out::println); sqlSession2.close(); }
- test result
- Seeing Cache Hit Ratio indicates that L2 cache has been enabled