1.引入
MyBatis的运行原理是学习MyBatis中一个比较重要的环节。同时在使用MyBatis的过程中我们经常会使用到插件的问题。这一个时候熟悉运行原理会对我们有较为大的帮助。
2.MyBatis运行原理简图
3.MyBatis运行原理解析(使用基础的Hello_World为例)
(1).MyBatis的插件开发
MyBatis在四大对象的创建过程中,都会有插件进行 介入。插件可以利用动态代理机制一层层的包装目标 对象,而实现在目标对象执行目标方法之前进行拦截 的效果。默认情况下,MyBatis 允许使用插件来拦截的方法调 用包括:
//执行器
Executor (update, query, flushStatements, commit, rollback,
getTransaction, close, isClosed)
//参数处理器
ParameterHandler (getParameterObject, setParameters)
//结果集处理器
ResultSetHandler (handleResultSets, handleOutputParameters)
//sql语句处理器
StatementHandler (prepare, parameterize, batch, update, query)
(2).MyBatis在执行HelloWorld的时候的执行流程
A、获取sqlSessionFactory对象
解析文件的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSession;
注意:【MappedStatement】:代表一个增删改查的详细信息
B、获取sqlSession对象
返回一个DefaultSQlSession对象,包含Executor和Configuration;这一步会创建Executor对象;
C、获取接口的代理对象(MapperProxy)
getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象代理对象里面包DefaultSqlSession(Executor)
D、执行增删改查方法
(3).sqlSessionFactory的初始化
SqlSessionFactory的初始化过程
1.通过读取配置文件mybatis-config.xml的内容,然后通过流的方式获取信息,并通过
SqlSessionFactoryBuilder().build(inputStream)的方式创建一个SqlSessionFactoryBuilder对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
2.如何获取配置文件中的每一个配置信息,源码解析如下:
//下钻
SqlSessionFactoryBuilder().build(inputStream);
>1:
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
>>2:
//xml文件解析器
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
>>>3:
//解析xml文件中的configuration节点(其实就是xml配置文件中的最大节点,即xml文件内容)
//然后把解析的信息保存
parseConfiguration(parser.evalNode("/configuration"));
>>>>4:
//其他部分解析省略
Properties settings = settingsAsPropertiess(root.evalNode("settings"));
mapperElement(root.evalNode("mappers"));
>>>>>5:
//解析每一个配置文件内容
configurationElement
String namespace = context.getStringAttribute("namespace");
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
>>>>>>6:
buildStatementFromContext
if (configuration.getDatabaseId() != null) {
buildStatementFromContext(list, configuration.getDatabaseId());
}
>>>>>>>7:
for (XNode context : list) {
final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration,
builderAssistant, context, requiredDatabaseId);
}
>>>>>>>>>8:
public void parseStatementNode() {
String id = context.getStringAttribute("id");
String databaseId = context.getStringAttribute("databaseId");
//............
}
3.在加载了所有的配置信息以后返回的是一个configuration,这里包含了所有的加载配置信息,里面包含了
很多比较重要的方法,接口以及变量等信息。
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
4.把获取的configuration对象再一次进行build,最终返回的是一个DefaultSqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
(4).OpenSession获取sqlSession
OpenSession获取sqlSession
返回SqlSession的实现类DefaultSqlSession对象。它里面包含了Executor和Configuration;
Executor被进一步创建。
(5).获取接口的代理对象(MapperProxy)
获取接口的代理对象(MapperProxy)
getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象代理对象里面包含了,DefaultSqlSession(Executor)
(6).查询实现
4.MyBatis运行原理总结
总结:
1、根据配置文件(全局,sql映射)初始化出Configuration对象;
2、创建一个DefaultSqlSession对象,他里面包含Configuration以及Executor(根据全局配置文件中的
defaultExecutorType创建出对应的Executor)
3、DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy;
4、MapperProxy里面有(DefaultSqlSession);
5、执行增删改查方法:
1)、调用DefaultSqlSession的增删改查(Executor);
2)、会创建一个StatementHandler对象。(同时也会创建出ParameterHandler和ResultSetHandler)
3)、调用StatementHandler预编译参数以及设置参数值;使用ParameterHandler来给sql设置参数
4)、调用StatementHandler的增删改查方法;
5)、ResultSetHandler封装结果。
注意:
四大对象每个创建的时候都有一个interceptorChain.pluginAll(parameterHandler);