Actuator of mybatis

Time:2022-4-30

In this article, let’s talk about the executors of mybatis, and see how to use different executors in different scenarios and the implementation principle of different executors (based on mybatis 3.4.6).

Knowledge points

  • What is an actuator
  • Mybatis actuator type and when to use it
  • Implementation principle of each actuator

    What is an actuator

    As the name suggests, the executor is used to execute our SQL statements to get the results or update the database. It is a very core concept in mybatis. It provides basic operation interfaces such as addition, modification, query and transaction management. Basically, everything is carried out around the actuator. See the figure below
    Actuator of mybatis

    Mybatis actuator type and when to use it

    Actuator type

    Let’s first take a look at what types of actuators mybatis currently has

  • SIMPLE
  • REUSE
  • BATCH
    At present, we can configure the above three kinds of actuators, and specify which one to use through defaultexecutortype (note that it is global). If it is configured through XML, refer to the official website
    Actuator of mybatis
    If spring boot integration is used, it is as follows
    Actuator of mybatis
    Let’s introduce the three actuators one by one.

    SIMPLE

    It can be understood as a basic actuator, which is also the default actuator of mybatis and the most commonly used actuator. We don’t need to make any configuration changes. Its general process is: open connection – > SET statement – > parameter injection – > execution – > result mapping – > Close statement. You can see that the statement will be closed after each use.

    REUSE

    You can tell by name that this is a reusable actuator. What is reusable? It means that the first two steps in the simple process can be reused, that is, open connection – > SET statement. These two steps will create a new statement, and the reuse executor will maintain a cache internally. After the first acquisition, the statement will be cached with the corresponding SQL (placeholder? Not replaced by specific parameters) as the key, and the statement will not be closed, If you encounter this SQL later, just start from step 3, which brings performance optimization (in fact, the optimization is not large).

    BATCH

    It can also be seen from the name that this is a batch actuator. What does batch mean? In other words, it can execute a batch of SQL statements at one time, mainly for modification operations such as update and insert. For single or query operations, do not use this actuator. Why can it be executed in batch? In fact, it is in the SQL packagePreparedStatementofaddBatch(), the principle will be explained in detail later.

    When to use

    After knowing the characteristics of the three types of actuators, let’s compare the performance output in different scenarios, so that we can know when to use which type of actuator. There is no comparison here because the insertion operation essentially uses the update operation interface. Based on mybatis used by spring, it is based on the following table structure
    Actuator of mybatis

    single query

    Code first

    DefaultSqlSessionFactory sqlSessionFactory = (DefaultSqlSessionFactory)applicationContext.getBean("sqlSessionFactory");
          //Choose the actuator type here
          DefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE);
          long startTime = System.currentTimeMillis();
    //        userInfoMapper.selectById(22222);
          defaultSqlSession.selectList("com.example.mybatisanalyze.mapper.UserInfoMapper.selectById", 22222);
          long endTime = System.currentTimeMillis();
          System.out.println((endTime - startTime) + "ms");

    simple:
    Actuator of mybatis
    As can be seen from the figure, it took 42ms
    reuse:
    takeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE);Change toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.REUSE);
    Actuator of mybatis
    As can be seen from the figure, it took 34ms
    batch:
    takeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE);Change toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.BATCH);
    Actuator of mybatis
    As can be seen from the figure, it took 43ms
    Conclusion: the three actuators for single query are similar, but it is recommended to choose simple. See the description in actuator type for the reason.

    Single insert

    Code first

    DefaultSqlSessionFactory sqlSessionFactory = (DefaultSqlSessionFactory)applicationContext.getBean("sqlSessionFactory");
          //The actuator type can be selected by yourself
          DefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE);
          long startTime = System.currentTimeMillis();
          UserInfo userInfo = new UserInfo();
          userInfo.setNickName("bbbcd");
          userInfo.setUserName("abcdc");
          userInfo.setBirthday(new Date());
          userInfo.setRegisterTime(LocalDateTime.now());
          userInfo.setEmail("12345");
          defaultSqlSession.insert("com.example.mybatisanalyze.mapper.UserInfoMapper.insert", userInfo);
          long endTime = System.currentTimeMillis();
          System.out.println((endTime - startTime) + "ms");

    simple:
    Actuator of mybatis
    As can be seen from the picture, it took 172ms
    reuse:
    In codeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE)Change this line toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.REUSE);
    Actuator of mybatis
    As can be seen from the figure, it took 178ms
    batch:
    In codeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE)Change this line toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.BATCH);
    Actuator of mybatis
    As can be seen from the figure, it took 176ms
    Conclusion: the performance of the three actuators is similar, so simple is recommended

    Batch insert

    Code first

    DefaultSqlSessionFactory sqlSessionFactory = (DefaultSqlSessionFactory)applicationContext.getBean("sqlSessionFactory");
          //Here, the actuator type can be selected by yourself
          DefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE);
          long startTime = System.currentTimeMillis();
          for (int i = 0; i < 10000; i++) {
              UserInfo userInfo = new UserInfo();
              userInfo.setNickName("bbbc");
              userInfo.setUserName("abcd");
              userInfo.setBirthday(new Date());
              userInfo.setRegisterTime(LocalDateTime.now());
              userInfo.setEmail("1234");
              defaultSqlSession.insert("com.example.mybatisanalyze.mapper.UserInfoMapper.insert", userInfo);
          }
          long endTime = System.currentTimeMillis();
          System.out.println((endTime - startTime) + "ms");

    Insert 10000 pieces of data
    simple:
    Actuator of mybatis
    As can be seen from the figure, it took 11762ms
    reuse:
    In codeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE)Change this line toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.REUSE);
    Actuator of mybatis
    As can be seen from the figure, it took 10992ms
    batch:
    In codeDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.SIMPLE)Change this line toDefaultSqlSession defaultSqlSession = (DefaultSqlSession)sqlSessionFactory.openSession(ExecutorType.BATCH);And add a commit operation after the for loopdefaultSqlSession.commit();
    Actuator of mybatis
    As can be seen from the figure, it took 6173ms
    Conclusion: obviously, batch should be selected

    Implementation principle of each actuator

    The logic related to mybatis and actuator isorg.apache.ibatis.executorBao Xia
    Actuator of mybatis
    Let’s take a look at the actuator interface firstorg.apache.ibatis.executor.Executor
    Actuator of mybatis
    Next, we can see the basic database operation system
    Actuator of mybatis
    You can see that the three actuators we use are subclasses, and two design patterns are used here, namelyBaseExecutorTemplate patterns andCachingExecutorDecorator mode implemented in. Let’s start at the entrance. The entrance isorg.apache.ibatis.session.defaults.DefaultSqlSession, here we provide basic operations based onselectOneMethods were analyzed untilorg.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)You will find that what he essentially calls is the query operation of the actuator
    Actuator of mybatis
    And where is this actuator generated? stayorg.apache.ibatis.session.defaults.DefaultSqlSessionFactoryWe callopenSessionMethod, we pass in the specified actuator type, or we can use the default, which will eventually beorg.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)Create actuators in
    Actuator of mybatis
    Here you can see that the corresponding actuator will be created according to the type of actuator passed in. Simple is used by default, andCachingExecutorFor a layer of packaging. Then, the query function above continues to analyze. We know that it will go to by defaultorg.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
    Actuator of mybatis
    The decorator mode is used here, and the L2 cache function is added to the original actuator function. In the end, it is calledorg.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)For execution, the first level cache is used here. If there is no cache, the database will be searched, that is, the method will be calledqueryFromDatabase
    Actuator of mybatis
    The template mode is used here,doQuery()It is implemented by subclasses themselves. The logic of each subclass actuator is relatively simple. Let’s introduce it hereBatchExecutor, others can see for themselves
    Actuator of mybatis
    It’s maintained herestatementListandbatchResultListThe corresponding execution results are stored in the objectdoUpdateIt will be recorded at the end of the dayhandler.batch()Call inPreparedStatementofaddBatchMethod, which is equivalent to temporarily storing instructions in the precompiler. We will call it later when we do commit ()doFlushStatementsMethod to do batch execution.

    summary

    There are still a lot of dry goods in this article. Basically, the executor of mybatis is introduced in detail and how to select the type. Of course, the bottom layer also involves some knowledge points of connection pool and SQL driver package. Later, the introduction of batch execution of SQL precompiler can be referred to https://blog.csdn.net/bluelin…

Recommended Today

Air quality of major cities in China using Baidu map official website in Vue – Baidu map case code

1. Add in the directory public/index.html <script></script> 2. Add the following code to the page <template> <div id=”MapChart” ref=”MapChart” style=”width: 600px;height:400px;”></div> </template> <script> import * as echarts from ‘echarts’ require(‘echarts/extension/bmap/bmap’) export default { name: ‘MapDemo’, components: {}, props: {}, data () { return { } }, computed: {}, watch: {}, created () {}, mounted () […]