initial commit

This commit is contained in:
Lostecho
2024-09-02 11:53:36 +08:00
commit cbac0ab8dd
565 changed files with 17862 additions and 0 deletions

136
pages/Mybatis源码.md Normal file
View File

@@ -0,0 +1,136 @@
- Mybatis初始化过程
- 通过InputStream来获取配置文件
- ClassLoaderWarpper中的getResourceAsStream可以根据配置的resoutce来获取到配置文件的输入六
- 使用ClassLoader是因为类加载器可具有读取外部资源的能力
- ![image.png](../assets/image_1714227673997_0.png)
- 读取到配置文件后传入SqlSessionFactoryBuilder内部使用XMLConfigBuilder的parse方法读取配置并set到一个configuration变量中返回一个Configuration对象
- ![image.png](../assets/image_1714228148958_0.png)
- 使用build方法创建一个DefaultSqlSessionFactory并返回
- 在其中会创建一个SqlSession其中会创建事务工厂之类的
- ![image.png](../assets/image_1714228719703_0.png)
- 将mapper类传入session通过session.getMapper方法在mapperRegistry获取到一个该mapper类的代理类MapperProxy
- 执行时会执行该代理类的invoke方法
- ![image.png](../assets/image_1714230626595_0.png)
- 触发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为去掉ifwhere标签的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将值赋值给对象