Create a learning process Mybatis source (23) -SqlSession object

I. Introduction

  In the previous content, we have analyzed each module base support layer Mybatis in subsequent analysis also the time to start working in Mybatis, how to load and parse the contents of the relevant configuration file. Details can refer to the "overall framework Mybatis Overview" , "initialization process when Mybatis start" content. In this section, we begin to analyze the process of creating SqlSession object.

Two, SqlSession objects Introduction

  SqlSession class is the central interface Mybatis interface layer, the interface is primarily used to execute the command, acquisition and management mapper transaction management. SqlSession instance is created by SqlSessionFactory instance. SqlSessionFactory object contains all methods to create SqlSession instance. The SqlSessionFactory itself is made SqlSessionFactoryBuilder created, it can be configured Java code from XML, Annotations or hand to create SqlSessionFactory. In SqlSession class contains numerous methods, it can be divided into several categories:

  • Execute the statement method
    These methods are used to execute SELECT defined in the XML file in SQL mapping, INSERT, UPDATE, and DELETE statements. They are pretty self explanatory, each of the statement of the ID attribute and the object parameters, the parameter may be a primitive (automatic packaging or packing), JavaBean, POJO or Map.

    <T> T selectOne(String statement, Object parameter)
    <E> List<E> selectList(String statement, Object parameter)
    <T> Cursor<T> selectCursor(String statement, Object parameter)
    <K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
    int insert(String statement, Object parameter)
    int update(String statement, Object parameter)
    int delete(String statement, Object parameter)
    
  • Batch method Update Now
    there is a way to refresh the batch (executed) is stored in the JDBC driver class update statement. When you use the ExecutorType.BATCH as ExecutorType this method can be used.

    List<BatchResult> flushStatements()
    
  • Transaction control method
    to control the transaction scope has four methods. Of course, if you've set up automatic commit or if you're using an external transaction manager, which have no effect. However, if you are using the JDBC transaction manager, managed by the Connection instance, then the four methods that will come in handy:

    void commit()
    void commit(boolean force)
    void rollback()
    void rollback(boolean force)
    
  • Local cache
    Mybatis to use two caches: local cache (local cache) and secondary cache (second level cache). Whenever a new session is created, MyBatis creates a local cache associated therewith. Any executed in the session query itself will be stored in the local cache, then the same query and change the same parameters generated by the second time it will not affect the database. Local cache will be additions and deletions, commit the transaction, the transaction is closed and the closure of the session empty. By default, locally cached data can be used within the entire period of the session, the cache needs to be used to resolve the circular reference errors and speed up the rate of repeat nested queries, so it can not all disabled, but you can set localCacheScope = sTATEMENT represents the cache is valid only when the statement is executed.

    void clearCache()
    
  • SqlSession Close
    to ensure SqlSession object is closed.

    void close()
    
  • Other methods
    the following three methods are used: Get Configuration configuration example; to obtain the mapping object; Get the current database connection object.

    Configuration getConfiguration()
    
    <T> T getMapper(Class<T> type)
    
    Connection getConnection();
    
Third, create SqlSession object methods

  SqlSession method creates an object, is made openSession SqlSessionFactory interface () methods or overloaded methods.

  SqlSessionFactory interfaces associated methods as follows:

//SqlSessionFactory.java
 SqlSession openSession(boolean autoCommit);
  SqlSession openSession(Connection connection);
  SqlSession openSession(TransactionIsolationLevel level);

  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);

  In Mybatis, the type of interface to achieve SqlSessionFactory two, namely: DefaultSqlSessionFactory, SqlSessionManager. Here the main analysis implementation SqlSession create objects DefaultSqlSessionFactory class. In the openSession () method, the bottom layer is achieved by a method openSessionFromDataSource (), the core logic is as follows:

//DefaultSqlSessionFactory.java
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      final Environment environment = configuration.getEnvironment();
      //根据mybatis中配置的环境,获取事务工厂,如果没有配置环境,就得到代理模式事务工厂ManagedTransactionFactory
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      //根据事务工厂创建事务实例对象
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //根据事务实例对象,还有执行器类型创建执行器
      final Executor executor = configuration.newExecutor(tx, execType);
      //创建默认的DefaultSqlSession实例对象,并返回
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

The method of the above logic is as follows:

  1. Environment variables Environment, has been in parsing the configuration file, stored in a globally unique variable configuration, so get directly through the get method.
  2. According to environment variables, create a transaction. First, create a transaction factory class TransactionFactory, then use newTransaction factory class () method to create a corresponding transaction instance.
  3. Creating objects Executor actuator, the configuration of the complete logic newExecutor () method.
  4. Finally, create SqlSession instance of an object, use DefaultSqlSession default implementation class.
Four, getTransactionFactoryFromEnvironment () method

  Examples of creating a transaction factory instance TransactionFactory according to the environment Environment. If the environment Environment instance is empty or does not contain examples of environmental affairs factory instance, you create a managed transaction mode factory instance ManagedTransactionFactory, otherwise, returns an instance environment.

//DefaultSqlSessionFactory.java
 private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
    if (environment == null  || environment.getTransactionFactory() == null) {
      return new ManagedTransactionFactory();
    }
    return environment.getTransactionFactory();
  }

  The plant TransactionFactory example newTransaction () method to create a Transaction corresponding instance, the process is actually create a Transaction EXAMPLES Example respective type according to the parameter, as an example below to JdbcTransactionFactory factory class, newTransaction () method source code as follows:

//JdbcTransactionFactory.java
  @Override
  public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
    return new JdbcTransaction(ds, level, autoCommit);
  }
Five, newExecutor () method, create an actuator Executor

  newExecutor () method in the Configuration class, the actuator is used to create SQL operations. The ExecutorType then create corresponding to the type of actuator may be BatchExecutor, ReuseExecutor SimpleExecutor or one, and then determines whether to open the caching mechanism, if the cache is turned on, then the package layer CachingExecutor, finally, by pluginAll InterceptorChain class () method dynamic all plug-ins defined, added to the actuator executor. About Plug-related content, please refer to "Mybatis interceptors to achieve pagination plug-in" .

//Configuration.java
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    //个人认为:该句代码有点儿多余,因为defaultExecutorType为空时,下面的判断语句还是默认会执行创建SimpleExecutor执行的代码
    //可能是考虑代码的可阅读性和代码逻辑的完整性(猜测)
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {//根据执行器类型创建BatchExecutor
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {//根据执行器类型创建ReuseExecutor
      executor = new ReuseExecutor(this, transaction);
    } else {//根据执行器类型创建SimpleExecutor
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {//如果开启全局缓存配置,则使用CachingExecutor包装executor
      executor = new CachingExecutor(executor);
    }
    //通过动态代理,把所有插件添加到执行器executor上
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
Published 48 original articles · won praise 3 · Views 3110

Guess you like

Origin blog.csdn.net/hou_ge/article/details/103734682