# mybatis-3
**Repository Path**: csuliunian/mybatis-3
## Basic Information
- **Project Name**: mybatis-3
- **Description**: mybatis源码
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-10-15
- **Last Updated**: 2024-06-29
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 基础
* [文档](http://mybatis.github.io/mybatis-3)
* [最新稳定版](https://github.com/mybatis/mybatis-3/releases)
* [快照版](https://oss.sonatype.org/content/repositories/snapshots/org/mybatis/mybatis/)
## 源码
### 如何获取数据源 datasource
通过BaseBuilder的实现类XMLConfigBuilder 解析配置文件,parse方法会返回解析完的Configuration类,解析过程中会获取到environments标签下的datasource的标签配置信息
```text
String id = child.getStringAttribute("id");
if (isSpecifiedEnvironment(id)) {
// 1. 事务管理工厂
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
// 2. 解析配置的数据源
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
// 3. 将解析获取到的数据源,事务管理工厂放到全局configuration中
DataSource dataSource = dsFactory.getDataSource();
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
configuration.setEnvironment(environmentBuilder.build());
}
```
### 如何获取sql
1. XMLMapperBuilder解析mapper的xml文件,获取到具体的insert delete update select,然后通过XMLStatementBuilder来解析,解析出的sql放入MapperBuilderAssistant
```text
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
if (namespace == null || namespace.isEmpty()) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
builderAssistant.setCurrentNamespace(namespace);
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
// resultMap
resultMapElements(context.evalNodes("/mapper/resultMap"));
// sql语句,公共的语句
sqlElement(context.evalNodes("/mapper/sql"));
// 实际的sql语句,分以下四种类型
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e);
}
}
```
```text
private void buildStatementFromContext(List list, String requiredDatabaseId) {
for (XNode context : list) {
final XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
try {
statementParser.parseStatementNode();
} catch (IncompleteElementException e) {
configuration.addIncompleteStatement(statementParser);
}
}
}
```
2. MapperAnnotationBuilder 解析@Mapper注解的类,该类上可以通过@Select注解编写sql语句
### 如何执行具体操作
#### 执行器类型
- SIMPLE
- REUSE
- BATCH
#### select
1. sqlSession.getOne/getList最终都会调用到getList
2. getList中用执行器Executor调用query方法
3. BaseExecutor.query 方法 调用子类实现的doQuery方法
4. doQuery方法中调用prepareStatement生成Statement
5. 然后交由StatementHandler去具体执行
```text
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
stmt = handler.prepare(connection, transaction.getTimeout());
handler.parameterize(stmt);
return stmt;
}
```
#### update insert delete