MyBatis 源码分析——映射结果

MyBatis最终一步一定是处理相关的结果——把数量映射成对应的模子对象。事实上在作者看来如若读者们精晓了mybatis怎么样去实践数据库,又是何等处理多少结果。那么就询问了mybatis的关键路径。因为无论是是如何样子的ORM最后都是要推行和处理结果的。而mybatis的独到之处笔者也讲了——管理sql语句。所以相对而言,处理结果就呈现煞是的次要。可是笔者如故期待能在这里滞留一下,琢磨他是如何处理结果。

mybatis处理结果的代码都在DefaultResultSetHandler类里面。很对不起的是笔者去掉了先后是怎样举办到DefaultResultSetHandler类的。这其间或者盼望读者们自行的去跟踪一下。DefaultResultSetHandler类的handleResultSets方法便是作者切入的代码。事实上当代码执行到handleResultSets方法的时候,已经举办了数据库。这在PreparedStatementHandler类里面就反映出来了。如下

  public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    return resultSetHandler.<E> handleResultSets(ps);
  }

用过mybatis的人都了然resultMap节点的功力。select节点的resultMap属性就是用来指导使用哪一个resultMap节点。而回到的结果也是用这个节点来安装的。如下

<select id="SelectProducts" resultMap="result" >
        select * from Products
        where #{0} > ProductID and ProductName like #{1}
</select>
<resultMap type="com.aomi.vo.Product" id="result" autoMapping="true">
</resultMap>

为此自己可以设想一下。当大家得到了数码的时候,希望多少变成我们指定的对象模型。那么我们就亟须了然是什么样品种。一般来讲只要领悟了怎么样类型就足以成功主旨的照耀条件。那么还会有可能出现一种希望自己去设计映射的字段和实例化对象。所以mybatis在这一方面也终究让笔者很喜爱。细详你可以查阅一下官方的网站——XML映射文件

在炫耀的过程中,往往大家都亟需知道表的字段。所以在DefaultResultSetHandler类的handleResultSets方法里面一开始就获取了关于表的信息。表的音信都存放在ResultSetWrapper类里面。前边便就是按照这多少个新闻来拍卖每一行的数额。我们如故看一下源码吧。

 1 public List<Object> handleResultSets(Statement stmt) throws SQLException {
 2     ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
 3 
 4     final List<Object> multipleResults = new ArrayList<Object>();
 5 
 6     int resultSetCount = 0;
 7     ResultSetWrapper rsw = getFirstResultSet(stmt);
 8 
 9     List<ResultMap> resultMaps = mappedStatement.getResultMaps();
10     int resultMapCount = resultMaps.size();
11     validateResultMapsCount(rsw, resultMapCount);
12     while (rsw != null && resultMapCount > resultSetCount) {
13       ResultMap resultMap = resultMaps.get(resultSetCount);
14       handleResultSet(rsw, resultMap, multipleResults, null);
15       rsw = getNextResultSet(stmt);
16       cleanUpAfterHandlingResultSet();
17       resultSetCount++;
18     }
19 
20     String[] resultSets = mappedStatement.getResultSets();
21     if (resultSets != null) {
22       while (rsw != null && resultSetCount < resultSets.length) {
23         ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
24         if (parentMapping != null) {
25           String nestedResultMapId = parentMapping.getNestedResultMapId();
26           ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
27           handleResultSet(rsw, resultMap, null, parentMapping);
28         }
29         rsw = getNextResultSet(stmt);
30         cleanUpAfterHandlingResultSet();
31         resultSetCount++;
32       }
33     }
34 
35     return collapseSingleResultList(multipleResults);
36   }

笔者标出切入需要的俩个代码段。一个就是赢得表新闻的,另一个即便用来拍卖每一行数据的。事实方面的multipleResults变量就能证实一个题目——可能实现多少个select句语的实践。所以相对的reusltMap也化为了汇集类型。在XML下边就是用逗号隔开的。笔者没有做过类似这种办法的代码。笔者也是从源码中看来的。他在MapperBuilderAssistant类的getStatementResultMaps方法里面。如下。

String[] resultMapNames = resultMap.split(",");

具体情状读者们得以团结去尝试一下。

在作者看来想要精晓这一部分的关键点还在是getRowValue方法这边。这之中就是我们所说的处理结果。依据reusltMap节点的音信判断出是要协调遵照项目变更对象。如故要透过reusltMap节点配置音讯来扭转对象。然后直行获值和设值。如下。

 1 private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
 2     final ResultLoaderMap lazyLoader = new ResultLoaderMap();
 3     Object resultObject = createResultObject(rsw, resultMap, lazyLoader, null);
 4     if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
 5       final MetaObject metaObject = configuration.newMetaObject(resultObject);
 6       boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();
 7       if (shouldApplyAutomaticMappings(resultMap, false)) {
 8         foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
 9       }
10       foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
11       foundValues = lazyLoader.size() > 0 || foundValues;
12       resultObject = foundValues ? resultObject : null;
13       return resultObject;
14     }
15     return resultObject;
16   }

1.createResultObject方法:依照项目和布局消息变更对象。

2.applyAutomaticMappings方法:判断是否是autoMapping=”true”,如果是就是自行映射赋值。

3.applyPropertyMappings方法:依照配置消息赋值。

接下去,就是各位读者们遵照自己的内需展开更进一步的探讨了。固然想知道是怎么转移对象就是去看createResultObject方法。赋值的话就去看applyAutomaticMappings方法和applyPropertyMappings方法。

网站地图xml地图