Skip to content

Latest commit

 

History

History
201 lines (179 loc) · 7.16 KB

Mybatis-MapperMethod.md

File metadata and controls

201 lines (179 loc) · 7.16 KB

MapperMethod

  • Author: HuiFer
  • Description: 该文介绍 mybatis MapperMethod 源码
  • 源码地址: org.apache.ibatis.binding.MapperMethod,核心方法是execute
  • 源码阅读工程: SourceHot-Mybatis
/** * CRUD 不同的执行处理 * * @param sqlSession * @param args * @return */publicObjectexecute(SqlSessionsqlSession, Object[] args) { Objectresult; switch (command.getType()) { caseINSERT: { Objectparam = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.insert(command.getName(), param)); break; } caseUPDATE: { Objectparam = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.update(command.getName(), param)); break; } caseDELETE: { Objectparam = method.convertArgsToSqlCommandParam(args); result = rowCountResult(sqlSession.delete(command.getName(), param)); break; } caseSELECT: if (method.returnsVoid() && method.hasResultHandler()) { executeWithResultHandler(sqlSession, args); result = null; } elseif (method.returnsMany()) { result = executeForMany(sqlSession, args); } elseif (method.returnsMap()) { result = executeForMap(sqlSession, args); } elseif (method.returnsCursor()) { result = executeForCursor(sqlSession, args); } else { Objectparam = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param); if (method.returnsOptional() && (result == null || !method.getReturnType().equals(result.getClass()))) { result = Optional.ofNullable(result); } } break; caseFLUSH: result = sqlSession.flushStatements(); break; default: thrownewBindingException("Unknown execution method for: " + command.getName()); } if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) { thrownewBindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } returnresult; }
/** * 根据 resultHandler 进行处理 * * @param sqlSession * @param args */privatevoidexecuteWithResultHandler(SqlSessionsqlSession, Object[] args) { MappedStatementms = sqlSession.getConfiguration().getMappedStatement(command.getName()); if (!StatementType.CALLABLE.equals(ms.getStatementType()) && void.class.equals(ms.getResultMaps().get(0).getType())) { thrownewBindingException("method " + command.getName() + " needs either a @ResultMap annotation, a @ResultType annotation," + " or a resultType attribute in XML so a ResultHandler can be used as a parameter."); } Objectparam = method.convertArgsToSqlCommandParam(args); // 判断是否有 RowBoundsif (method.hasRowBounds()) { RowBoundsrowBounds = method.extractRowBounds(args); sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args)); } else { sqlSession.select(command.getName(), param, method.extractResultHandler(args)); } }
  • 返回值为多个的情况
/** * 针对多个查询结果进行 ,转换成不同的 list 或者数组 * * @param sqlSession * @param args * @param <E> * @return */private <E> ObjectexecuteForMany(SqlSessionsqlSession, Object[] args) { List<E> result; Objectparam = method.convertArgsToSqlCommandParam(args); if (method.hasRowBounds()) { RowBoundsrowBounds = method.extractRowBounds(args); // 直接 listresult = sqlSession.selectList(command.getName(), param, rowBounds); } else { result = sqlSession.selectList(command.getName(), param); } // issue #510 Collections & arrays supportif (!method.getReturnType().isAssignableFrom(result.getClass())) { if (method.getReturnType().isArray()) { // 转换成 arrayreturnconvertToArray(result); } else { // 转换成 collectionreturnconvertToDeclaredCollection(sqlSession.getConfiguration(), result); } } returnresult; }

convertToArray

/** * 转换为数组 * * @param list 数据库查询结果 * @param <E> * @return */@SuppressWarnings("unchecked") private <E> ObjectconvertToArray(List<E> list) { // 获取返回类型Class<?> arrayComponentType = method.getReturnType().getComponentType(); // new 一个 arrayObjectarray = Array.newInstance(arrayComponentType, list.size()); if (arrayComponentType.isPrimitive()) { for (inti = 0; i < list.size(); i++) { Array.set(array, i, list.get(i)); } returnarray; } else { // 通过 toArray方法转换returnlist.toArray((E[]) array); } }

convertToDeclaredCollection

/** * 转换为不同的list对象 * * @param config * @param list 数据库查询结果 * @param <E> * @return */private <E> ObjectconvertToDeclaredCollection(Configurationconfig, List<E> list) { // mybatis ObjectFactory 创建mapper 的返回结果对象Objectcollection = config.getObjectFactory().create(method.getReturnType()); MetaObjectmetaObject = config.newMetaObject(collection); // metaObject.objectWrapper => CollectionWrapper// MetaObject 对象的 objectWrapper 现在是 CollectionWrapper 它是 Collection 的包装metaObject.addAll(list); returncollection; }
  • 上述两个为转换的过程,其实质还是在 org.apache.ibatis.session.SqlSession 中做执行操作

debug

  • 修改 mapper 返回数组对org.apache.ibatis.binding.MapperMethod#convertToArray方法进行测试
HsSell[] list(@Param("ID") Integerid);

image-20191219092442456

  • 修改 mapper,对org.apache.ibatis.binding.MapperMethod#convertToDeclaredCollection进行测试

    LinkedList<HsSell> list(@Param("ID") Integerid);

image-20191219093043035

close