Mybatis Source Code Analysis

In this article, we will read the source code of Mybatis in depth, hoping that we can not be so afraid of the underlying framework in the future, and learn the good ideas of framework design;

Architectural principles

Architecture diagram

Architectural flow chart

The two pictures above are from the internet, but they are very good. They basically illustrate the architecture of Mybatis.

Explain:

  1. Mybatis configuration file

    • SqlMapConfig.xml, as the global configuration file of mybatis, configures the running environment of mybatis and other information.
    • Mapper.xml, which serves as the sql mapping file of mybatis, is configured with sql statements to operate the database. This file needs to be loaded in SqlMapConfig.xml.
  2. SqlSessionFactory

    • SqlSession Factory is constructed through configuration information such as mybatis environment, i.e. session factory.
  3. SqlSession

    • SqlSession is created by session factory, and programmers add, delete and check the database through sqlsession session interface.
  4. Executor Actuator

    • The bottom layer of mybatis customizes the Executor executor interface to operate the database. The Executor interface has two implementations, one is the basic executor (default), the other is the cache executor, and the bottom layer of sqlsession operates the database through the executor interface.
  5. MappedStatement

    • It is also a mybatis underlying encapsulation object, which wraps mybatis configuration information and sql mapping information. A selectinsertupdatedelete tag in mapper.xml file corresponds to a Mapped State object. The id of the selectinsertupdatedelete tag is the id of the Mapped State.
    • Mapped Statement defines the input parameters of SQL execution, including HashMap, basic type, pojo. Executor maps the input java object to SQL through Mapped Statement before executing sql. The input parameter mapping is the setting parameters of preparedStatement in jdbc programming.
    • Mapped Statement defines the output result of sql execution, including HashMap, basic type and pojo. Executor maps the output result to java object after executing sql through Mapped Statement. The output result mapping process is equivalent to the parsing process of the result in jdbc programming.

Call flow chart

Executor

MyBatis executor, the core of MyBatis scheduling, is responsible for generating SQL statements and maintaining query cache.

StatementHandler

The JDBC statement operation is encapsulated and responsible for the operation of JDBC statement, such as setting parameters and converting Statement result set into List set.

ParameterHandler

Responsible for converting parameters passed to users into parameters required by JDBC Statement

ResultSetHandler

Responsible for converting the ResultSet result set object returned by JDBC into a collection of List type

TypeHandler

Responsible for mapping and transformation between java data types and jdbc data types

SqlSource

Responsible for generating SQL statements dynamically according to the parameterObject passed by users, encapsulating the information into the BoundSql object, and returning the boundSql to represent the dynamically generated SQL statements and corresponding parameter information.

Source code parsing

Loading global configuration files

  • Looking for entries: SqlSessionFactoryBuilder build method
SqlSessionFactoryBuilder#Building SqlSessionFactory
    XMLConfigBuilder#parse global profile parsing, encapsulated as a Configuration object
        #parseConfiguration parses from the root path and loads information into the Configuration object
            #MaperElement parses mapper mapping files
                XMLMapperBuilder#parse parses mapper mapping files
                    SqlSessionFactoryBuilder#build: Create the default implementation class for the SqlSessionFactory interface
  • summary
1. When SqlSessionFactory Builder creates SqlsessionFactory, it needs to pass in a Configuration object. 
2. The XMLConfigBuilder object will de-instantiate Configuration. 
3. The XMLConfigBuilder object initializes the Configuration object. 
    Using XPathParser to parse global configuration files and form Document objects 
    Get the XNode object of the specified node through XPathParser. 
    Parse the information of the Xnode object and encapsulate it in the Configuration object
  • Related classes and interfaces
|--SqlSessionFactoryBuilder 
|--XMLConfigBuilder 
|--XPathParser 
|--Configuration

Load mapping configuration file

  • Looking for entries: XMLConfigBuilder#mapperElement method
XMLConfigBuilder#mapperElement: Resolve the < mappers > tag in the global configuration file 
    |--XMLMapperBuilder#Constructor: Specialized for parsing mapping files 
        |--XPathParser#Construction method: 
            |--XPathParser#createDocument(): Create Document objects corresponding to Mapper mapping files 
            |--MapperBuilderAssistant#Constructor: Used to construct MappedStatement objects 
        |--XMLMapperBuilder#parse():  
            |--XMLMapperBuilder#Configuration Element: Specialized for parsing mapper mapping files 
                |--XMLMapperBuilder#BuilStatementFromContext: Used to create MappedStatement objects 
                    |--XMLMapperBuilder#buildStatementFromContext 
                        |--XMLStatementBuilder#Constructor: Specialized for parsing MappedStatement 
                        |--XMLStatementBuilder#parseStatementNode: 
                            |--MapperBuilderAssistant#addMappedStatement: Create MappedStatement objects 
                                |--MappedStatement.Builder#Construction method 
                                |--MappedStatement.Builder#build method: Create MappedStatement object and store it in Configuration object
  • Related interfaces and classes
|--XMLConfigBuilder 
|--XMLMapperBuilder 
|--XPathParser 
|--MapperBuilderAssistant 
|--XMLStatementBuilder 
|--MappedStatement

SqlSource Creation Process

  • Looking for entries: XML Language Driver # createSqlSource
XMLLanguageDriver#createSqlSource creates SqlSource, parses SQL, encapsulates SQL statements (output parameter binding) and input information

​    XMLScriptBuilder Constructor: Initialization dynamics SQL The set of node processors in
​        XMLScriptBuilder#parseScriptNode 
​            #parseDynamicTags parses the SQL statements in the select insert update delete tag, and eventually encapsulates the parsed SqlNode into the List collection in Mixed SqlNode
​            DynamicSqlSource Construction method: if SQL Including ${}And dynamics SQL Statement, then the SqlNode Encapsulated to DynamicSqlSource
​            RawSqlSource Construction method: if SQL Including#{}, SqlNode is encapsulated in RawSqlSource and a parameterType is specified
​                SqlSourceBuilder#parse
​                    ParameterMappingTokenHandler Construction method
​                        GenericTokenParser#Construct method, specify openToken and closeToken to be analyzed, and specify processor
​                            GenericTokenParser#parse analysis#{}
​                                ParameterMappingTokenHandler#handleToken  Handle token(#{}/${})
​                                    #Build Parameter Mapping to create Parameter Mapping objects
​                                StaticSqlSource Constructing the method, which will be parsed after the ___________ sql Information, encapsulated to StaticSqlSource object
  • Related classes and interfaces
|--XMLLanguageDriver 
|--XMLScriptBuilder 
|--SqlSource 
|--SqlSourceBuilder

Creating Mapper Proxy Objects

  • Find the entrance: DefaultSqlSession#getMapper
|--DefaultSqlSession#getMapper: Get the Mapper proxy object 
​    |--Configuration#getMapper: Get the Mapper proxy object 
​        |--MapperRegistry#getMapper: Get the proxy object through the proxy object factory 
​            |--MapperProxyFactory#New Instance: Call JDK's dynamic proxy mode to create Mapper proxy

SqlSession executes the main process

  • Find the entrance: DefaultSqlSession#selectList()
DefaultSqlSession#selectList
​    CachingExecutor#query
​        BaseExecutor#query delegates execution to BaseExecutor
​            #queryFromDatabase
​            SimpleExecutor#doQuery Executes Queries
​                Configuration#New Statement Handler creates a Statement Handler for routing functions, based on the Statement Type in MappedStatement
​            SimpleExecutor#prepareStatement Sets PreapreStatement Parameters
​            BaseExecutor#GettConnection Gets a Database Connection
​                BaseStatementHandler#prepare creates Statement PrepareStatement, Statement, Callable Statement
​                PreparedStatementHandler#parameterize setting parameters
​                PreparedStatementHandler#query executes the SQL statement (parameters have been set) and maps the result set
​                    com.mysql.jdbc.PreparedStatement#Excute calls JDBC's api to execute Statement
​                        DefaultResultSetHandler#handleResultSets process result sets
  • Related interfaces and classes
|--DefaultSqlSession 
|--Executor 
    |--CachingExecutor 
    |--BaseExecutor 
    |--SimpleExecutor 
|--StatementHandler 
    |--RoutingStatementHandler 
    |--PreparedStatementHandler 
|--ResultSetHandler 
    |--DefaultResultSetHandler 

BoundSql acquisition process

  • Looking for entries: MappedStatement#getBoundSql method
MappedStatement#getBoundSql
​    DynamicSqlSource#getBoundSql 
​        SqlSourceBuilder#parse Execution parsing: will have#The {} SQL statement is parsed and encapsulated in StaticSqlSource
​            GenericTokenParser  #Construct method, specify openToken and closeToken to be analyzed, and specify processor
​                GenericTokenParser#parse parses SQL statements to handle content in openToken and closeToken 
​                    ParameterMappingTokenHandler#handleToken Handle token(#{}/${})  
​                        #Build Parameter Mapping to create Parameter Mapping objects
​                            StaticSqlSource#Construction method: encapsulate parsed SQL information into StaticSqlSource
|--RawSqlSource#getBoundSql 
​    |--StaticSqlSource#getBoundSql 
​        |--BoundSql#Constructing method: The parsed sql information, parameter mapping information and input object are combined into the BoundSql object. 

Parametric mapping process

  • Looking for entries: It's actually Prepared Statement Handler # parameterize in the SqlSession execution process

|--PreparedStatementHandler#parameterize: Set the parameters of PreparedStatement 
​    |--DefaultParameterHandler#setParameters: Set parameters 
​        |--BaseTypeHandler#setParameter:  
​            |--xxxTypeHandler#setNonNullParameter: Call the setxxx method of PreparedStatement

Processing result sets

  • Looking for entries: DefaultResultSetHandler#handleResultSets in the SqlSession execution process
|--DefaultResultSetHandler#handleResultSets 
​    |--DefaultResultSetHandler#handleResultSet 
​        |--DefaultResultSetHandler#handleRowValues 
​            |--DefaultResultSetHandler#handleRowValuesForSimpleResultMap 
​                |--DefaultResultSetHandler#getRowValue 
​                    |--DefaultResultSetHandler#createResultObject: Create a mapping result object 
​                    |--DefaultResultSetHandler#applyAutomaticMappings 
​                    |--DefaultResultSetHandler#applyPropertyMappings 

Basically, that's how Mybatis works, and there are many implementation details that you can't understand for the time being. I think the learning framework source code is divided into two steps:

  1. Grasp the main line, grasp the principle and process of the framework;
  2. After understanding the processing ideas, we should understand the object-oriented ideas and the usage of design patterns.

At present, there are still some problems in the first step. We need to go through the source code several times to deepen our understanding and refuel together.~~

Keywords: Java SQL Mybatis JDBC xml

Added by mjlively on Sun, 28 Jul 2019 16:17:06 +0300