[Mybatis source code] 1. The creation process and function of SqlSession

Structure diagram

The relationship between the core components of mybatis can be represented by the following diagram:

Among them, add "I" before the class name to indicate the interface

SqlSessionFactoryBuilder

As can be seen from the figure, in addition to Configuration, the class name of each class contains a "SqlSession", as can be seen from the structure diagram, our ultimate goal is to create SqlSession, SqlSession can be temporarily understood as jdbc in Connection, execute sql through SqlSession.

SqlSessionFactoryBuilder, as the name suggests, is the builder of SqlSessionFactory.

The only responsibility of the SqlSession is to build the SqlSessionFactory. There are also various construction methods. You can pass in the Reader object of the configuration file, the input stream, or directly pass in a packaged configuration class.

Configuration

The Configuration class has already appeared in the SqlSessionFactoryBuilder above, and there are many configuration items in this class.

These configuration items will be initialized once at startup. (either via code, or via configuration files)

You can see the relationship between Configuration and SqlSessionFactory.

(DefaultSqlSessionFactory is an implementation class of SqlSessionFactory, which will be mentioned later)

There is only one constructor of DefaultSqlSessionFactory, and Configuration is required as a configuration class. SqlSessionFactory usually corresponds to a data source. A data source has only one Factory instance, so Configuration will also reside in memory.

Recalling my first encounter with mybatis, when springboot has not been used, it is often necessary to maintain an xml configuration file.

All configuration items in this configuration file correspond to Configuration one-to-one.

SqlSessionFactory

SqlSessionFactory is an interface with two implementation classes SqlSessionManager and DefaultSqlSessionFactory.

It has a single responsibility and is only used to create a SqlSession.

public interface SqlSessionFactory {

  //8 methods you can use to create a SqlSession instance
  SqlSession openSession();

  //auto commit
  SqlSession openSession(boolean autoCommit);
  //connect
  SqlSession openSession(Connection connection);
  //Transaction isolation level
  SqlSession openSession(TransactionIsolationLevel level);

  //type of actuator
  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);

  Configuration getConfiguration();

}

Creation process:

  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      //Generate a transaction through a transaction factory
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //Generate an executor (transactions are included in the executor)
      final Executor executor = configuration.newExecutor(tx, execType);
      //Then generate a DefaultSqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      //If there is an error opening the transaction, close it
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      //Finally clear the error context
      ErrorContext.instance().reset();
    }
  }

The approximate logic is as follows:

1. Generate a transaction through the transaction factory

The transaction object consists of the following parts

Data connection object, data source, transaction isolation information, whether to commit automatically.

The data connection object (Connection) can be absent, because it can be obtained from the data source.

So we can see that mybatis got the Environment object from the configuration class and got the data source.

2. Generate the executor

After getting the transaction object, wrap it up to become an Executor.

Executor is responsible for the final execution of sql.

3. Create SqlSession

SqlSession

Finally to the protagonist, SqlSession.

SqlSession is also an interface with only two implementation classes, SqlSessionManager and DefaultSessionManager.

The more commonly used is DefaultSessionManager.

In fact, the main components of SqlSession can be seen from the above creation process.

new DefaultSqlSession(configuration, executor, autoCommit);

Configuration class, executor, the last parameter indicates whether to automatically commit the transaction.

The intention is quite obvious, which is clearly to let SqlSession do the most critical work - calling executor to execute sql statements.

Where does the sql statement come from?

It can be seen from the open method interface of SqlSession that mybatis encapsulates some common database operations, and it is no surprise that SqlSession is the window for receiving sql.

we write a sql

public interface RoleMapper {
    public Role getRole(@Param("id") Long id);
}

corresponding xml

<select id="getRole" parameterType="long" resultMap="roleMap">
        select
        id,role_name as roleName,note from role where id=#{id}
</select>

Will eventually call the second method of SqlSession

<T> T selectOne(String statement, Object parameter);

statement does not refer to the final sql, but corresponds to the mapper method in mybatis (mapper interface).

The second parameter is usually a map or pojo object. For example, although only one parameter id is passed in the above case, mybatis will also be encapsulated into a map. See below:

Find MappedStatement through the method name of mapper, and hand it over to the executor to execute sql.

This article is an overview, which will be summarized later based on some specific implementations.

If there is any mistake, welcome to criticize and correct!

Tags: Mybatis

Posted by egmax on Mon, 07 Nov 2022 05:38:32 +0300