一:架构
1、架构理解:
mybatis架构主要分为三层:
1、接口层: 提供api接口,也就是mapper相关。
包含:sqlSession
2、数据处理层: 处理数据的。 将参数组装生成动态sql,执行后将结果封装返回。
包含:Executor,StatementHandler,ParameterHandler,ResultSetHandler,
TypeHandler,MappedStatement,BoundSql,SqlSource(负责根据⽤户传递的parameterObject,动态地⽣成SQL语句,将信息封装到BoundSql)
3、支撑层:底层事务、链接、缓存等管理。 为处理层做支撑。
2、执行流程:
a、容器启动
加载并解析配置文件到Configuration(可以基于注解或xml文件)。
将sql配置信息加载到MappedStatement。
b、api调用
通过调用mapper接口,传入参数。
通过mapper接口的全路径,对应着mapper.xml中namespace + id,确定statementid, 找到sql。
解析生成动态的sql并执行。
将结果封装并返回。
二:mybatis源码解析
在之前已简单写过持久层框架,只是读取了个别标签配置。 在mybatis中有很多的标签,现在来看一下:
原生api调用流程
1、初始化流程:
首先我们会读取xml,创建SqlSessionFactory。
Inputstream inputstream = Resources.getResourceAsStream("mybatis-config.xml");
//这⼀⾏代码正是初始化⼯作的开始。
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory就是mybatis提供的,这里开始进入源码。
build方法经过重载,最终到以下方法:
parser.parse()创建了Configuration,里面都包含了一些什么信息:
如上,解析了很多的标签,包括之前手写过的mappers标签。
对于mappers中的每一个mapper.xml,都会解析成一个个的MappedStatement,具体对应着一个个的select/update/insert/delete节点,最终存放在Configuration中
Map < String , MappedStatement > mappedStatements = new StrictMap < MappedStatement > ( "Mapped Statements collection" )
2、sql执行流程:
sql的执行是先通过获取SqlSession开始,然后调用它提供的api:
SqlSession sqlSession = factory.openSession();
List<User> list = sqlSession.selectList("com.mapper.UserMapper.getUserByName");
SqlSession通常与ThreadLocal绑定,⼀个会话使⽤⼀ 个 ,使用完后需要调用close()关闭。
openSession():
public SqlSession openSession() {
//getDefaultExecutorType传递的是SimpleExecutor
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}
openSessionFromDataSource():
/**
*ExecutorType 为Executor的类型,TransactionIsolationLevel为事务隔离级别,
*autoCommit是否开启事务;
*openSession的多个重载⽅法可以指定获得的SeqSession的Executor类型和事务的处理
*/
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//根据参数创建指定类型的Executor
Executor executor = this.configuration.newExecutor(tx, execType);
//返回DefaultSqlSession
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().rese