mybatis resultmap 如何为对象赋值的调用顺序

 更新时间:2022年01月28日 15:30:08   作者:qq_34922536  
这篇文章主要介绍了mybatis resultmap 如何为对象赋值的调用顺序,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

resultmap 为对象赋值的调用顺序

写了一个mybatis的mapper映射文件,

java bean定义如下

public class GroupCourseResult extends GroupResult {
    private String cid;
    private String cname;
    public GroupCourseResult(int stuschool, int nian, String stuclass, String cid, String cname) {
        super(stuschool, nian, stuclass);
        this.cid = cid;
        this.cname = cname;
    }
    public String getCid() {
        return cid;
    }
    public void setCid(String cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
}

部分mybatis映射文件如下

<select id="selectFailedCourseRationByGroupIdAndCourseName" resultType="GroupCourseResult">
      ...
  </select>

实体类中的属性名和查询的列名完全匹配,但是没有查询stuclass,则封装后的实体类中的stuclass属性应该为空。

然而程序运行后,stuclass属性不仅不为空,还与cname完全相同,百思不得其解,故翻了翻mybatis的源码。

在mybatis中的DefaultResultSetHandler类中,

createResultObject方法的代码如下

  private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix)
      throws SQLException {
    final Class<?> resultType = resultMap.getType();
    final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory);
    final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings();
    if (hasTypeHandlerForResultObject(rsw, resultType)) {
      return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
    } else if (!constructorMappings.isEmpty()) {
      return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix);
    } else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
      return objectFactory.create(resultType);
    } else if (shouldApplyAutomaticMappings(resultMap, false)) {
      return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs);
    }
    throw new ExecutorException("Do not know how to create an instance of " + resultType);
  }

经过调试发现,mybatis会先查找该javabean有无默认构造方法,如果有则采用设值注入,若没有,则根据javabean的有参构造方法进行设值,而在8以前的jdk版本中,我们利用反射只能获取到参数类型,不能获取到参数名称,这其中设值可能出现了匹配失误,将cname的值同时赋给了cname和stuclass。

想要解决这个问题,只须在javabean中添加默认构造方法即可。

使用resultMap时需注意的问题

如果是实体中是直接引用别的对象的具体参数字段,

直接用原始方式就行

    <resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
        <id column="id" property="id"/>
        <result column="visitNumber" property="visitNumber"/>
        <result column="patientName" property="patientName"/>
        <result column="sendTime" property="sendTime"/>
        <result column="wardCode" property="wardCode"/>
        <result column="wardName" property="wardName"/>
        <result column="categoryCode" property="categoryCode"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="cover" property="cover"/>
    </resultMap>
    
    <select id="getAllBy" resultMap="baseMap">
        SELECT
            eer.visit_number as visitNumber,
            eer.patient_name as patientName,
            eer.send_time as sendTime,
            eek.id as id,
            eek.ward_code as wardCode,
            eek.ward_name as wardName,
            eek.category_code as categoryCode,
            eek.title as title,
            eek.content as content,
            eek.cover as cover
        FROM
            edu_education_record AS eer,
            edu_education_knowledge AS eek
        WHERE
            eer.education_knowledge_id=eek.id
    </select>

如果是实体中是list集合

    <resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
    	<id column="id" property="id"/>
        <result column="visitNumber" property="visitNumber"/>
        <result column="patientName" property="patientName"/>
        <result column="sendTime" property="sendTime"/>
        <result column="wardCode" property="wardCode"/>
        <result column="wardName" property="wardName"/>
        <result column="categoryCode" property="categoryCode"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="cover" property="cover"/>
        
        <collection property="pic" ofType="string">
            <result column="pic"/>
        </collection>
    </resultMap>
    
    <select id="getAllBy" resultMap="baseMap">
        SELECT
            eer.visit_number as visitNumber,
            eer.patient_name as patientName,
            eer.send_time as sendTime,
            eek.id as id,
            eek.ward_code as wardCode,
            eek.ward_name as wardName,
            eek.category_code as categoryCode,
            eek.title as title,
            eek.content as content,
            eek.cover as cover
        FROM
            edu_education_record AS eer,
            edu_education_knowledge AS eek
        WHERE
            eer.education_knowledge_id=eek.id
    </select>

如果实体中引用的是别的对象,

使用association 标签来写

    <resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
        <id column="id" property="id"/>
        <result column="wardCode" property="wardCode"/>
        <result column="wardName" property="wardName"/>
        <result column="categoryCode" property="categoryCode"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="cover" property="cover"/>
        
        <association property="eduEducationRecord" javaType="com.ei.medical.modules.model.EduEducationRecord">
	        <result column="visitNumber" property="visitNumber"/>
	        <result column="patientName" property="patientName"/>
	        <result column="sendTime" property="sendTime"/>
        </association>
    </resultMap>
    
    <select id="getAllBy" resultMap="baseMap">
        SELECT
            eer.visit_number as visitNumber,
            eer.patient_name as patientName,
            eer.send_time as sendTime,
            eek.id as id,
            eek.ward_code as wardCode,
            eek.ward_name as wardName,
            eek.category_code as categoryCode,
            eek.title as title,
            eek.content as content,
            eek.cover as cover
        FROM
            edu_education_record AS eer,
            edu_education_knowledge AS eek
        WHERE
            eer.education_knowledge_id=eek.id
    </select>

如果实体中是引用的别的对象的list集合,

应该使用collection标签

<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
        <id column="id" property="id"/>
        <result column="wardCode" property="wardCode"/>
        <result column="wardName" property="wardName"/>
        <result column="categoryCode" property="categoryCode"/>
        <result column="title" property="title"/>
        <result column="content" property="content"/>
        <result column="cover" property="cover"/>
        
        <collection property="eduEducationRecordList" ofType="com.ei.medical.modules.model.EduEducationRecord">
            <result column="visitNumber" property="visitNumber"/>
            <result column="patientName" property="patientName"/>
            <result column="sendTime" property="sendTime"/>
        </collection>
    </resultMap>
    <select id="getAllBy" resultMap="baseMap">
        SELECT
            eer.visit_number as visitNumber,
            eer.patient_name as patientName,
            eer.send_time as sendTime,
            eek.id as id,
            eek.ward_code as wardCode,
            eek.ward_name as wardName,
            eek.category_code as categoryCode,
            eek.title as title,
            eek.content as content,
            eek.cover as cover
        FROM
            edu_education_record AS eer,
            edu_education_knowledge AS eek
        WHERE
            eer.education_knowledge_id=eek.id
    </select>

tips:

使用resultMap的时候,应该直接用as后面的字段名,即自己命的名字

如果没有使用as的话,直接使用数据库中原本的名字

resultMap中各个标签的含义

在这里插入图片描述

tips:

在一个 resultMap 元素中,这些子元素出现的先后顺序是有严格规定的,它们从前到后依次是:constructor–>id --> result–> association–>collection -->discriminator, 不然就会报错。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Jenkins之Log Parse使用方法详解

    Jenkins之Log Parse使用方法详解

    这篇文章主要为大家详细介绍了Jenkins插件Log Parse使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • eclipse/IDEA配置javafx项目步骤(图文教程)

    eclipse/IDEA配置javafx项目步骤(图文教程)

    这篇文章主要介绍了eclipse/IDEA配置javafx项目步骤(图文教程),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Spring Boot 整合 MongoDB的示例

    Spring Boot 整合 MongoDB的示例

    这篇文章主要介绍了Spring Boot 整合 MongoDB的示例,帮助大家更好的理解和学习spring boot框架,感兴趣的朋友可以了解下
    2020-10-10
  • java连接hdfs ha和调用mapreduce jar示例

    java连接hdfs ha和调用mapreduce jar示例

    这篇文章主要介绍了Java API连接HDFS HA和调用MapReduce jar包,需要的朋友可以参考下
    2014-03-03
  • Idea中Springboot热部署无效问题解决

    Idea中Springboot热部署无效问题解决

    这篇文章主要介绍了Idea中Springboot热部署无效问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java处理日期时间的方法汇总

    Java处理日期时间的方法汇总

    这篇文章主要给大家介绍了利用Java中的Calendar 类处理日期时间的方法汇总,其中包括取日期的每部分、取当月的第一天或最后一天、求两个日期之间相隔的天数以及一年前的日期等等的示例代码,有需要的朋友们可以直接参考借鉴,下面来一起看看吧。
    2016-12-12
  • 利用synchronized实现线程同步的案例讲解

    利用synchronized实现线程同步的案例讲解

    这篇文章主要介绍了利用synchronized实现线程同步的案例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 详解Java变量与常量

    详解Java变量与常量

    这篇文章主要介绍了Java变量与常量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • javaweb 国际化:DateFormat,NumberFormat,MessageFormat,ResourceBundle的使用

    javaweb 国际化:DateFormat,NumberFormat,MessageFormat,ResourceBu

    本文主要介绍javaWEB国际化的知识,这里整理了详细的资料及实现代码,有兴趣的小伙伴可以参考下
    2016-09-09
  • Spring Cloud Gateway(读取、修改 Request Body)的操作

    Spring Cloud Gateway(读取、修改 Request Body)的操作

    这篇文章主要介绍了Spring Cloud Gateway(读取、修改 Request Body)的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12

最新评论