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

目录
  • Mybatis使用resultMap属性赋值顺序错误
    • ids是后加入的字段
    • resultMap中是这样写的
    • 解决办法
  • 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, 不然就会报错。

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

(0)

相关推荐

  • Mybatis中ResultMap解决属性名和数据库字段名不一致问题

    目录 前言 1. 字段名不一致 解决方法: 第一种方式: 起别名 第二种方式: 结果集映射 resultMap 2. 多对一处理 3. 一对多处理 小结 前言 我们Pojo类的属性名和数据库中的字段名不一致的现象时有发生,简单的情况我们可以开启驼峰命名法解决大小写问题,但是遇到其它非大小写问题,我们就不得不使用Mybatis中的结果集映射resultMap. 1. 字段名不一致 数据库中的字段 我们项目中实体类的字段 public class User { private int id; pri

  • mybatis mapper互相引用resultMap启动出错的解决

    目录 mybatis mapper互相引用resultMap启动出错 问题 原因 解决方法 mybatis resultMap引发的吐血bug 简单的讲 以下是详细的 利用mybatis读取数据时,发生不可理解的事情 mybatis mapper互相引用resultMap启动出错 问题 Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for kulink.cv

  • mybatis使用resultMap获取不到值的解决方案

    mybatis resultMap获取不到值 <resultMap type="com.fc.model.Shop" id="employeeMap"> <id column="shop_id" property="shopId"></id> <result column="name" property="name"></result

  • 解决resultMap映射数据错误的问题

    目录 resultMap映射数据错误 解决方案 [报错]resultMap认知错误 附图(修改过后的) resultMap映射数据错误 mapper文件使用了resultMap进行一对多关系映射,不管怎么配置(没有问题)SQL语句查询出来的结果,和调用mapper代理对象产生的entry数据就是不一致. 解决方案 在mapper的sql语句中加上order by. [报错]resultMap认知错误 数据库改了一个字段的名字,后来牵扯到实体类标准化都要改,原来以为,mybatis使用的sql语句

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

    目录 Mybatis使用resultMap属性赋值顺序错误 ids是后加入的字段 resultMap中是这样写的 解决办法 Mybatis使用resultMap时需注意 Mybatis使用resultMap属性赋值顺序错误 今天发现个坑,新建的表使用生成工具生成的mapper文件和实体类后,发现少了个字段就又手动加了下,结果发现一个问题 ids是后加入的字段 @Data @Builder public class QueryRecordPo {        //若干其他属性....     p

  • 关于MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据)

    数据准备 数据表 CREATE TABLE `teacher`( id INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO `teacher`(id,`name`) VALUES(1,'大师'); CREATE TABLE `student`( id INT(10) NOT NULL, `name` VARCHAR

  • Mybatis collection查询集合属性报错的解决方案

    目录 Mybatis collection查询集合属性报错 错误日志 背景 排查 解决方法 MyBatis 包含属性为集合的查询 父实体类 关联子查询实体类 父查询返回结果实体类映射 集合子查询实体类映射 父查询 子查询 Mybatis collection查询集合属性报错 错误日志 org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, cla

  • java 面向对象代码块及不同位置对属性赋值的执行顺序

    目录 代码块 对属性可以赋值的位置 不同位置对属性赋值的执行顺序 结语 前言: java中的代码块介绍以及一个类中不同位置对属性赋值的执行顺序. 代码块 1.代码块的作用:用来初始化类.对象 2.代码块如果有修饰的话,只能使用 static 3.分类:静态代码块 VS 非静态代码块 4.静态代码块 内部可以有输出语句. 随着类的加载而执行,而且只执行一次. 作用:初始化类的信息. 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行. 静态代码块的执行要优先于非静态代码块的执行. 静态代码

  • MyBatis拦截器:给参数对象属性赋值的实例

    该拦截器的作用:在进行增加.修改等操作时,给数据模型的一些通用操作属性(如:创建人.创建时间.修改人.修改时间等)自动赋值. 该实现是在DAO层拦截,即存入DB前最后一层.后经分析,不是很合理,改为在service层拦截,用spring AOP来实现了,该代码遂弃用.不过已经测试可用,记录备忘. package com.development; import java.lang.reflect.InvocationTargetException; import java.util.Date; i

  • 解决mybatis无法给带有下划线属性赋值问题

    目录 mybatis无法给带有下划线属性赋值问 1.配置问题 2.增加set方法转换值的方式 解决方法 实体类中有下滑线字段无法赋值问题 mybatis无法给带有下划线属性赋值问 1.配置问题 <!-- 是否开启自动驼峰命名规则(camel case)映射, --> <setting name="mapUnderscoreToCamelCase" value="true"/> 或者 //开启驼峰映射         bean.getObjec

  • MyBatis查询时属性名和字段名不一致问题的解决方法

    问题 当我们数据库中的字段和实体类中的字段不一致的时候,查询会出问题 数据库字段是 pwd id name pwd 1 张三 123456 2 李四 123456 3 王五 123456 4 赵六 123456 实体类字段是 password public class User { private int id; private String name; private String password; } 查出来结果发现, password 是 null User{id=1, name='张三

  • Java循环对bean的属性进行赋值的实现

    项目背景 我们开发过程中会碰到这样一类问题,就是数据层或三方接口返回的Bean对象需要转换重新装换一下我们需要的对象.我们通常的做法就是通过getter/setter方法进行一个一个进行赋值,这样的话书写起来太复杂了,并且太重复了.我尝试写了一个工具类,能够对各种场景下的对象进行相互赋值. 功能介绍 可以为将要赋值的对象进行单个单个的按顺序赋值 通过传递的属性的index(就是他是第几个属性)获取本属性的值 返回对象中属性的数量 两个对象之间相互拷贝属性值 传递一个list,遍历bean进行赋值

  • Mybatis中resultMap的Colum和property属性详解

    目录 resultMap的Colum和property属性 1: resultMap标签 2:使用情况 2.1 简单查询 2.2 一对一 2.3 一对多 resultMap对column和property的理解 select元素有很多属性(这里说用的比较多的) 什么时候我们知道使用resultMap,什么时候又使用resultType呢? 最后说下 resultMap的Colum和property属性 1: resultMap标签 当我们的数据库字段与实体类的属性不一致时,就需要使用该标签进行一

随机推荐