136 lines
6.2 KiB
Markdown
Executable File
136 lines
6.2 KiB
Markdown
Executable File
- Mybatis初始化过程
|
||
- 通过InputStream来获取配置文件
|
||
- ClassLoaderWarpper中的getResourceAsStream可以根据配置的resoutce来获取到配置文件的输入六
|
||
- 使用ClassLoader是因为类加载器可具有读取外部资源的能力
|
||
- 
|
||
- 读取到配置文件后传入SqlSessionFactoryBuilder,内部使用XMLConfigBuilder的parse方法读取配置并set到一个configuration变量中返回一个Configuration对象
|
||
- 
|
||
- 使用build方法创建一个DefaultSqlSessionFactory并返回
|
||
- 在其中会创建一个SqlSession,其中会创建事务工厂之类的
|
||
- 
|
||
- 将mapper类传入session,通过session.getMapper方法在mapperRegistry获取到一个该mapper类的代理类MapperProxy
|
||
- 执行时会执行该代理类的invoke方法
|
||
- 
|
||
- 触发mapperMethod的execute方法
|
||
- ```java
|
||
public Object execute(SqlSession sqlSession, Object[] args) {
|
||
Object result;
|
||
switch (command.getType()) {
|
||
case *INSERT*: {
|
||
Object param = method.convertArgsToSqlCommandParam(args);
|
||
result = rowCountResult(sqlSession.insert(command.getName(), param));
|
||
break;
|
||
}
|
||
case *UPDATE*: {
|
||
Object param = method.convertArgsToSqlCommandParam(args);
|
||
result = rowCountResult(sqlSession.update(command.getName(), param));
|
||
break;
|
||
}
|
||
case *DELETE*: {
|
||
Object param = method.convertArgsToSqlCommandParam(args);
|
||
result = rowCountResult(sqlSession.delete(command.getName(), param));
|
||
break;
|
||
}
|
||
case *SELECT*:
|
||
if (method.returnsVoid() && method.hasResultHandler()) {
|
||
executeWithResultHandler(sqlSession, args);
|
||
result = null;
|
||
} else if (method.returnsMany()) {
|
||
result = executeForMany(sqlSession, args);
|
||
} else if (method.returnsMap()) {
|
||
result = executeForMap(sqlSession, args);
|
||
} else if (method.returnsCursor()) {
|
||
result = executeForCursor(sqlSession, args);
|
||
} else {
|
||
Object param = method.convertArgsToSqlCommandParam(args);
|
||
result = sqlSession.selectOne(command.getName(), param);
|
||
if (method.returnsOptional()
|
||
&& (result == null || !method.getReturnType().equals(result.getClass()))) {
|
||
result = Optional.*ofNullable*(result);
|
||
}
|
||
}
|
||
break;
|
||
case *FLUSH*:
|
||
result = sqlSession.flushStatements();
|
||
break;
|
||
default:
|
||
throw new BindingException("Unknown execution method for: " + command.getName());
|
||
}
|
||
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
|
||
throw new BindingException("Mapper method '" + command.getName()
|
||
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
|
||
}
|
||
return result;
|
||
}
|
||
```
|
||
- 会根据不同的语句类型执行不同的execute方法,查询list会执行executeForMany方法
|
||
- ```java
|
||
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
|
||
List<E> result;
|
||
Object param = method.convertArgsToSqlCommandParam(args);
|
||
if (method.hasRowBounds()) {
|
||
RowBounds rowBounds = method.extractRowBounds(args);
|
||
result = sqlSession.selectList(command.getName(), param, rowBounds);
|
||
} else {
|
||
result = sqlSession.selectList(command.getName(), param);
|
||
}
|
||
*// issue #510 Collections & arrays support
|
||
* if (!method.getReturnType().isAssignableFrom(result.getClass())) {
|
||
if (method.getReturnType().isArray()) {
|
||
return convertToArray(result);
|
||
} else {
|
||
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
```
|
||
- selectList获取MappedStatement,再执行executor.query方法
|
||
- ```java
|
||
@Override
|
||
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
|
||
BoundSql boundSql = ms.getBoundSql(parameterObject);
|
||
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
|
||
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
|
||
}
|
||
```
|
||
- BoundSql为去掉if,where标签的sql语句,Cachekey为缓存key
|
||
- 查询时先从缓存获取,获取不到或list为null就执行delegate.query方法查询
|
||
- 检查executor是否被关闭,是否清理缓存
|
||
- 通过queryFromDatabase,先在缓存中放一个占位符,接着使用doQuery方法查询,然后把缓存中的占位符换成真正的结果
|
||
- ```java
|
||
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
|
||
List<E> list;
|
||
localCache.putObject(key, *EXECUTION_PLACEHOLDER*);
|
||
try {
|
||
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
|
||
} finally {
|
||
localCache.removeObject(key);
|
||
}
|
||
localCache.putObject(key, list);
|
||
if (ms.getStatementType() == StatementType.*CALLABLE*) {
|
||
localOutputParameterCache.putObject(key, parameter);
|
||
}
|
||
return list;
|
||
}
|
||
```
|
||
- 执行doQuery方法,为BatchExecutor类的方法
|
||
- ```java
|
||
public <E> List<E> doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
|
||
throws SQLException {
|
||
Statement stmt = null;
|
||
try {
|
||
flushStatements();
|
||
Configuration configuration = ms.getConfiguration();
|
||
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql);
|
||
Connection connection = getConnection(ms.getStatementLog());
|
||
stmt = handler.prepare(connection, transaction.getTimeout());
|
||
handler.parameterize(stmt);
|
||
return handler.query(stmt, resultHandler);
|
||
} finally {
|
||
closeStatement(stmt);
|
||
}
|
||
}
|
||
```
|
||
- 通过Statement执行静态语句获取结果
|
||
- 执行的是PrepareStatementHandler.query方法,获取结果后交给ResultSetHandler处理,通过resultMap将值赋值给对象 |