Java Mybatis使用resultMap时,属性赋值顺序错误的巨坑

 更新时间:2022年01月20日 09:49:25   作者:百事可乐_  
这篇文章主要介绍了Java Mybatis使用resultMap时,属性赋值顺序错误的巨坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Mybatis使用resultMap属性赋值顺序错误

今天发现个坑,新建的表使用生成工具生成的mapper文件和实体类后,发现少了个字段就又手动加了下,结果发现一个问题

ids是后加入的字段 

@Data
@Builder
public class QueryRecordPo {
 
     //若干其他属性....
    private String outputField;
     //后加的
    private String ids;
 
    //若干其他属性
    //... 
}

resultMap中是这样写的

    <resultMap id="BaseResultMap" type="....">
        <id column="id" jdbcType="BIGINT" property="id"/>
        ..若干其他属性
        <result column="ids" jdbcType="VARCHAR" property="ids"/>
        <result column="output_field" jdbcType="VARCHAR" property="outputField"/>
        ..若干其他属性
    </resultMap>

可以发现ids加的位置是不一样的,实体类中在outputField属性下面,但resultMap中在其上面。然后测试数据中ids字段为null,查询出来时却发现ids的值和outputField的值是一样的。但如果ids的字段有值,就可以正确赋值。

mybatis在生成目标类进行映射时,会先检查构造函数声明情况,但 如果Data注解和Builder注解一块使用的话就只会生成全属性参数构造函数,不会有默认无参构造函数。全属性构造函数的参数顺序是和类中属性声明顺序一致的

在把数据库字段映射到实体类的时候发现实体类没有默认无参构造函数,就会把数据库中的字段按照全属性构造函数参数的顺序依次赋值给实体类的属性。但如果实体类的属性定义顺序与数据库中字段顺序不一致,就会出现赋值错误的情况。

然后再为outputField字段赋值时调用了set方法 这样就出现了两个不同名但同值的属性。

解决办法

1 修改属性顺序保持一致

2 为实体类加上@NoArgsConstructor和 @AllArgsConstructor注解 使其可以生成无参数构造函数即可

之前生成时 顺序都保持了一致,还真没发现这个问题

Mybatis使用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, 不然就会报错。

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

您可能感兴趣的文章:

相关文章

  • Java Web 简单的分页显示实例代码

    Java Web 简单的分页显示实例代码

    这篇文章主要介绍了Java Web 简单的分页显示实例代码的相关资料,本文通过,计算总的页数和查询指定页数据两个方法实现分页效果,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • javaweb实现简易邮件发送

    javaweb实现简易邮件发送

    这篇文章主要为大家详细介绍了javaweb实现简易邮件发送,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • JAVA实现简单系统登陆注册模块

    JAVA实现简单系统登陆注册模块

    这篇文章主要介绍了一个简单完整的登陆注册模块的实现过程,文章条理清晰,在实现过程中加深了对相关概念的理解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-07-07
  • Java微信公众号开发之通过微信公众号获取用户信息

    Java微信公众号开发之通过微信公众号获取用户信息

    这篇文章主要介绍了Java微信公众号开发之通过微信公众号获取用户信息,需要的朋友可以参考下
    2017-05-05
  • Java中private关键字详细用法实例以及解释

    Java中private关键字详细用法实例以及解释

    这篇文章主要给大家介绍了关于Java中private关键字详细用法实例以及解释的相关资料,在Java中private是一种访问修饰符,它可以用来控制类成员的访问权限,文中将用法介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 详解如何在Spring Security中自定义权限表达式

    详解如何在Spring Security中自定义权限表达式

    这篇文章主要和大家详细介绍一下如何在Spring Security中自定义权限表达式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-07-07
  • Java如何有效避免SQL注入漏洞的方法总结

    Java如何有效避免SQL注入漏洞的方法总结

    SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库,这篇文章主要给大家介绍了关于Java如何避免SQL注入漏洞的两种方法,需要的朋友可以参考下
    2022-01-01
  • SpringCloud远程服务调用实战笔记

    SpringCloud远程服务调用实战笔记

    本文给大家介绍SpringCloud远程服务调用实战笔记,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-11-11
  • SpringCloud使用logback日志框架教程详解

    SpringCloud使用logback日志框架教程详解

    Logback是一个功能强大的日志框架,它是一个基于slf4j的日志系统,提供了可靠的日志服务,比log4j更快,更灵活,更容易使用。本文将教会你快速让你的项目集成logback日志框架,需要的朋友可以参考下
    2023-05-05
  • Java正则表达式实现在文本中匹配查找换行符的方法【经典实例】

    Java正则表达式实现在文本中匹配查找换行符的方法【经典实例】

    这篇文章主要介绍了Java正则表达式实现在文本中匹配查找换行符的方法,结合具体实例分析了java正则匹配查找换行符的实现技巧与匹配模式相关操作注意事项,需要的朋友可以参考下
    2017-04-04

最新评论