Mybatisplus映射实体类改变字段顺序映射出错问题解决

当Mybatisplus的xml字段顺序与实体类字段顺序不一致,且实体类因@AllArgsConstructor注解缺失无参构造函数时,会导致映射错误。源码解析表明,实体类有无参构造方法时按字段名映射,否则按顺序映射。解决方案包括移除@AllArgsConstructor或手动添加@NoArgsConstructor。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

xml内容如下

<select id="XXX" resultType="XXX.XX.AppResubscribeVO">
        SELECT app.app_name,
               app_id,
               spec.spec_name,
               ...

实体类如下

@Data
@AllArgsConstructor
public class AppResubscribeVO
{
   
    @ApiModelProperty(value = "应用名")
    private String appName;

    @ApiModelProperty(value = "规格名")
    private String specName;

    @ApiModelProperty(value = "应用ID")
    private Integer appId;
   ...

如图,xml的字段(app_id,spec_name)和实体的字段(specName,appId)顺序不一致,且两个字段的类型也不一致,分别是String和Integer。此时又加了注解@AllArgsConstructor全参构造函数,则没有默认的无参构造函数。这种情况就会导致映射实体出错。

源码剖析

此问题的核心源码mybatisplus是
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix)
其他过程源码略
我们来看一下这个方法
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix)
      throws SQLException {
   
    final Class<?> resultType = resultMap.getType()
### MyBatis-Plus 实体类映射添加教程 #### 1. 定义实体类 在 MyBatis-Plus 中,实体类通常用于与数据库表进行映射。可以通过 Lombok 注解简化代码编写过程。以下是定义一个简单的 `Teacher` 实体类的示例: ```java import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data @TableName("t_teacher") // 指定对应的数据库表名称 public class Teacher { private Long id; // 主键字段,默认自动映射到数据库中的 id 列 private String name; // 教师姓名 private Integer age; // 年龄 @TableLogic // 使用逻辑删除功能 private Boolean deleted; // 默认情况下 false 表示未删除,true 表示已删除[^5] } ``` --- #### 2. 配置 Mapper 接口 MyBatis-Plus 提供了一个通用接口 `BaseMapper<T>` 来实现基本的 CRUD 功能。通过继承该接口并指定泛型参数为具体的实体类即可完成基础操作。 ```java import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface TeacherMapper extends BaseMapper<Teacher> { // 可在此扩展自定义 SQL 方法 } ``` --- #### 3. 编写 XML 文件 (可选) 虽然 MyBatis-Plus 支持无 XML 的开发模式,但在某些复杂场景下仍需手动编写 XML 文件来定义查询语句。以下是一个完整的 `TeacherMapper.xml` 示例: ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.TeacherMapper"> <!-- 查询所有教师 --> <select id="queryAll" resultType="com.example.entity.Teacher"> SELECT * FROM t_teacher WHERE deleted = 0 </select> </mapper> ``` 注意:如果启用了逻辑删除,则需要显式过滤掉被标记为已删除的数据[^3]。 --- #### 4. 测试查询方法 可以利用 Spring Boot 提供的测试框架验证实体类映射是否正常工作。下面展示了一种基于 JUnit 的单元测试方式: ```java import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @SpringBootTest public class TeacherServiceTest { @Autowired private TeacherMapper teacherMapper; @Test public void testQueryAll() { List<Teacher> teachers = teacherMapper.queryAll(); System.out.println(teachers); } } ``` 上述代码调用了 `teacherMapper.queryAll()` 方法获取所有未被逻辑删除的记录,并打印结果列表[^4]。 --- #### 5. 全局配置优化 为了进一步提升开发效率,可以在项目的 `application.yml` 或者 `application.properties` 文件中统一设置一些常用选项,比如主键策略、逻辑删除规则等。 ```yaml mybatis-plus: global-config: db-config: id-type: auto # 设置为主键自增模式 logic-delete-field: deleted # 自定义逻辑删除字段名为 deleted logic-delete-value: 1 # 数据库中表示已删除的状态值 logic-not-delete-value: 0 # 数据库中表示未删除的状态值 ``` 以上配置能够减少重复劳动,使项目更加规范化和易于维护。 --- ### 注意事项 当使用 Lombok 的 `@Builder` 注解时需要注意可能引发的问题。例如,在反序列化过程中可能会因为构造器不匹配而导致异常发生。因此建议仅在必要场合才启用此特性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值