MyBatis Principle Analysis - Basic Principles

foreword

MyBatis is a widely used persistence framework. A simple usage example is as follows, first create a session factory, then open a session from the session factory, generate a proxy implementation of the Mapper interface through class type and configuration, and finally use Mapper for persistence operations.

 

This article will briefly analyze the implementation principle of MyBatis from the aspects of SqlSessionFactoryBuilder, SqlSessionFactory, SqlSession and Mapper in MyBatis. In the following series of articles, the detailed implementation of the core class will be further analyzed in detail.

 

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder uses Builder mode to generate SqlSessionFactory, so it only provides multiple build methods. These methods can accept the Reader or InputStream input stream of the XML configuration file, and can also pass in environment to specify the environment or pass in Properties as properties.

 

In the implementation of the build method, first build the XMLConfigBuilder object according to the incoming input stream, environment and Properties, then call its parse() method to parse the XML file to get the Configuration object, and finally create the SqlSessionFactory object and return it.

 

SqlSessionFactory

SqlSessionFactory is a factory interface, and the default implementation is DefaultSqlSessionFactory. The role of SqlSessionFactory is to obtain SqlSession, so it provides multiple openSession methods to support creating SqlSession from DataSource data source and a given connection Connection.

 

The underlying implementation of the openSession method can be divided into 5 steps:

①Get the environment configuration Environment from the Configuration object;

②Get the transaction factory TransactionFactory according to the environment configuration;

③ Get the transaction transaction from the transaction factory, which wraps the database connection and handles the creation, preparation, submission, rollback and closing of the database connection;

④Create an executor Executor;

⑤ Create SqlSession and return an instance of DefaultSqlSession.

The process of creating a SqlSession from a DataSource data source is as follows:

    Transaction tx =null;
    try{
    finalEnvironment environment = configuration.getEnvironment();
    finalTransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
    finalExecutor executor = configuration.newExecutor(tx, execType);
    returnnewDefaultSqlSession(configuration, executor, autoCommit);
    }catch(Exception e){
    closeTransaction(tx);// may have fetched a connection so lets call close()
    throwExceptionFactory.wrapException("Error opening session. Cause: "+ e, e);
    }finally{
    ErrorContext.instance().reset();
    }

 

 

SqlSession

SqlSession is an interface, the default implementation is DefaultSqlSession, which provides a variety of database operation methods, such as select, selectOne, selectList, insert, update, delete, commit, rollback and getMapper. The getMapper method is used to get the proxy implementation of the Mapper interface. It is recommended to use the Mapper interface to operate the database in MyBatis.

 

The addition, deletion, modification, and query of the database and the commit and rollback of the transaction are all performed through the Executor. Executor has 3 types SIMPLE, REUSE, BATCH, the default use simple executor SIMPLE, REUSE type executor reuse prepared statement, BATCH type executor reuse prepared statement and batch update. The creation of the Executor object takes place in the newExecutor method of the Configuration type.

 

During the execution process of Executor, StatementHandler, ParameterHandler and ResultHandler are used, among which StatementHandler encapsulates the related operations of java.sql.Statement, ParameterHandler encapsulates the processing of SQL parameters, and ResultHandler encapsulates the processing of returned data sets. The execution process of Executor is the scheduling process of these three objects. More analysis will be carried out in subsequent articles.

 

Mapper

Mapper is implemented through JDK dynamic proxy. MapperProxy is created in MapperProxyFactory and encapsulated by interface proxy. Calls to the Mapper interface are actually implemented by MapperProxy.

 

    @SuppressWarnings("unchecked")
    protected T newInstance(MapperProxy<T> mapperProxy){
    return(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{ mapperInterface }, mapperProxy);
    }
     
    public T newInstance(SqlSession sqlSession){
    finalMapperProxy<T> mapperProxy =newMapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
    }

 

 

In MapperProxy, the invoke method of InvocationHandler is implemented. methodCache is a ConcurrentHashMap that stores the correspondence between methods and MapperMethods. Get or create a MapperMethod object from the methodCache cache, and then call the execute method of the MapperMethod object to perform database operations.

 

    @Override
    publicObject invoke(Object proxy,Method method,Object[] args)throwsThrowable{
    try{
    if(Object.class.equals(method.getDeclaringClass())){
    return method.invoke(this, args);
    }elseif(isDefaultMethod(method)){
    return invokeDefaultMethod(proxy, method, args);
    }
    }catch(Throwable t){
    throwExceptionUtil.unwrapThrowable(t);
    }
    finalMapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
    }
     
    privateMapperMethod cachedMapperMethod(Method method){
    MapperMethod mapperMethod = methodCache.get(method);
    if(mapperMethod ==null){
    mapperMethod =newMapperMethod(mapperInterface, method, sqlSession.getConfiguration());
    methodCache.put(method, mapperMethod);
    }
    return mapperMethod;
    }

 

 

When the MapperMethod object is created, the SqlCommand and MethodSignature are initialized in the constructor. SqlCommand contains the name of the database operation in the format of "interface name.operation name", and the operation type configured in XML, such as select, update, etc., combines a Mapper interface with a configuration in XML. MethodSignature is the signature of the method, marking the return value type of the method. For methods that use RowBounds (offset and limit configuration), ResultHandler (result processing callback) as parameters, the parameter location is recorded and the parameter handler is initialized.

 

In the execute method of MapperMethod, select the method of SqlSession according to the configuration in SqlCommand, process the incoming parameters according to the configuration of MethodSignature, call the method of SqlSession for database operation, and finally return the operation result according to the return value type of MethodSignature.

 

3 study notes or technical summaries per week, aimed at Java programmers with a certain foundation, covering Java advanced, virtual machine, MySQL, NoSQL, distributed computing, open source framework and other fields. Follow the author or WeChat public account backend-develop to get the latest content as soon as possible.

MyBatis Principle Analysis--Basic Principle

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326615354&siteId=291194637