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:
-
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.
-
SqlSessionFactory
- SqlSession Factory is constructed through configuration information such as mybatis environment, i.e. session factory.
-
SqlSession
- SqlSession is created by session factory, and programmers add, delete and check the database through sqlsession session interface.
-
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.
-
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:
- Grasp the main line, grasp the principle and process of the framework;
- 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.~~