6.2 KiB
6.2 KiB
- 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方法
-
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方法
-
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方法
-
@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方法查询,然后把缓存中的占位符换成真正的结果
-
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类的方法
-
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将值赋值给对象