Mybatis是一个半自动化ORM框架,可以将数据库中的记录转换为java实体对象,但是java实体属性通常采用驼峰命名法,而数据库字段习惯采用下划线分隔命名法,因此需要用户指定java实体属性与数据库表字段之间的映射关系。 mybatis的Mapper 配置中提供了resultMap 标签,用于建立数据库字段与java实体属性之间的映射关系。例如:

<resultMap id="userMap" type="com.th.entity.User">
    <result column="id" property="id"></result>
    <result column="user_name" property="username"></result>
    <result column="pass_word" property="password"></result>
    <result column="bithday" property="bithday"></result>
    <collection property="orderList" ofType="com.th.entity.Order" fetchType="lazy">
      <result column="oid" property="id"></result>
      <result column="order_time" property="ordertime"></result>
      <result column="total" property="total"></result>
    </collection>
  </resultMap>

Mybatis 在启动时,所有配置信息都会被转换为java对象,Mybatis 通过ResultMap类描述resultMap标签的配置信息;在XMLMapperBuilder类的configurationElement()方法中,调用resultMapElements()方法对所有resultMap标签进行解析。resultMapElements()方法最终会调用重载的resultMapElement()方法对每个resultMap标签进行解析。代码如下:

mybatis resultType 父类的字段映射不到_mybatis

对resultMap标签解析完成后,在StatementHandler组件与数据库完成交互后,需要根据resultMap标签的配置把结果转换为Resultmap对象,就会使用ResultSetHandler组件对结果集进行处理。

在PreparedStatementHandler.query方法中,调用PreparedStatement.execute() 方法完成与数据库交互之后,会调用resultSetHandler.handleResultSets()方法对结果集进行处理。代码如下:

mybatis resultType 父类的字段映射不到_嵌套_02


DefaultResultSetHandler类是ResultSetHandler接口的唯一默认实现,DefaultResultSetHandler.handleResultSets()方法中,简化了对JDBC中ResultSet对象的操作,将ResultSet对象包装成ResultSetWrapper对象,然后获取MappedStatement对象对应的ResultMap对象,然后再调用重载的HandleResultSet()方法进行处理,代码如下:

mybatis resultType 父类的字段映射不到_嵌套_03

在重载的handleResultSet()方法中做了些逻辑判断,最终都会调用handleRowValues()方法进行处理,代码如下:

mybatis resultType 父类的字段映射不到_结果集_04


handleRowValues()方法中判断ResultMap中是否有嵌套的ResultMap,当使用association或collection标签通过JOIN查询方式进行级联映射时 ,HasNestedResultMaps()方法返回true;如果有嵌套的RresultMap,则调用handleRowValuesForNestedResultMap()方法进行处理,否则调用handleRowValuesForSimpleResultMap()方法,代码如下:

mybatis resultType 父类的字段映射不到_mybatis_05

简单映射结果处理

handleRowValuesForSimpleResultMap()方法不含嵌套映射的简单映射的处理。

mybatis resultType 父类的字段映射不到_嵌套_06

嵌套映射结果处理

handleRowValuesForNestedResultMap ()方法是对嵌套映射结果进行处理,在处理过程中,对结果集对象进行遍历,处理每一行数据,首先调用resolveDiscriminatedResultMap()方法处理resultmap标签中通过discriminator标签配置的鉴别器信息,根据字段值获取对应的ResultMap对象,然后调用getRowValue() 方法将结果集中的一行数据转换为java实体对象。

mybatis resultType 父类的字段映射不到_java_07


简单映射结果和嵌套映射结果调用了getRowValue() 方法将结果集中的一行数据转换为java实体对象。代码如下:

mybatis resultType 父类的字段映射不到_java_08

多结果集处理

针对多结果集处理,在getRowValue()方法中调用 applyPropertyMappings()方法映射ResultMap中明确指定的字段。代码如下:

mybatis resultType 父类的字段映射不到_嵌套_09


applyPropertyMappings()会调用getPropertyMappingValue()方法完成映射操作,代码如下:

mybatis resultType 父类的字段映射不到_java_10

getPropertyMappingValue()会调用addPendingChildRelation()对多结果集的情况进行处理,处理代码如下:

mybatis resultType 父类的字段映射不到_mysql_11