MyBatis踩坑记录-多表关联字段相同,字段数据覆盖问题

1. 背景描述

现有一下业务,单个任务下可能会有多个子任务,现将通过关联查询将子任务放在单个任务下,类似于这样的数据结构:

{
    "task": {
        "id": "1",
        "name": "a",
        "createTime": "2024-07-03 17:15:00"
    },
    "info": [
        {
            "id": "01",
            "name": "aa",
            "createTime": "2024-07-03 17:15:00"
        },
        {
            "id": "001",
            "name": "aaa",
            "createTime": "2024-07-03 17:15:00"
        },
        {
            "id": "0001",
            "name": "aaaa",
            "createTime": "2024-07-03 17:15:00"
        }
    ]
}

2. 实体记录

public class TaskInfoVO {
    private TaskDO task;
    private List<SubTaskInfo> subTaskInfos;
}

/**
 * 任务总表
 * @TableName task_list
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaskDO implements Serializable {
    private Long id;
    private String name;
    private Date createTime;
    private static final long serialVersionUID = 1L;
}

/**
 * 子任务
 * @TableName task_list
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.ALWAYS)
public class SubTaskInfo implements Serializable {
	private Long id = 0L;
	private String name;
    private Date createTime;
    private static final long serialVersionUID = 1L;

3. 错误映射


<resultMap id="TaskInfoVOMap" type="com.iqiyi.auto.module.heal.controller.VO.TaskInfoVO">
        <association property="task" javaType="com.iqiyi.auto.module.heal.DO.TaskDO">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        </association>
        <collection property="subTaskInfos" ofType="com.iqiyi.auto.module.heal.DTO.SubTaskInfo" notNullColumn="id">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        </collection>
    </resultMap>

3.1 造成的影响

错误图片

4. 解决办法

4.1 修改映射文件


<resultMap id="TaskInfoVOMap" type="com.iqiyi.auto.module.heal.controller.VO.TaskInfoVO">
        <association property="task" javaType="com.iqiyi.auto.module.heal.DO.TaskDO">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="task_name" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        </association>
        <collection property="subTaskInfos" ofType="com.iqiyi.auto.module.heal.DTO.SubTaskInfo" notNullColumn="id">
            <id property="id" column="id_sub" jdbcType="BIGINT"/>
            <result property="name" column="name_sub" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time_sub" jdbcType="TIMESTAMP"/>
        </collection>
    </resultMap>

5. 修复后的效果

5.1 返回的数据

修复后的截图

5.2 正确展示

正确展示

7. end ~

一天上一当,当当不一样,坑坑多多

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过编写一个事务来实现修改多表中的一个编码的操作,并且保证修改后的编码在多表编码字段中不重复。 具体步骤如下: 1. 首先,在你的 DAO 层中定义一个方法,用于更新需要修改编码的表中的编码字段。例如,如果你需要修改的表是 `table1`,那么该方法可以如下所示: ```java @Mapper public interface Table1Mapper { int updateCode(@Param("oldCode") String oldCode, @Param("newCode") String newCode); } ``` 其中 `oldCode` 是需要修改的编码,`newCode` 是修改后的编码。 2. 然后,在你的 Service 层中编写一个事务来保证多表修改的原子性。例如,如果你需要同时修改 `table1` 和 `table2` 两张表中的编码字段,那么该事务可以如下所示: ```java @Service public class MyService { @Autowired private Table1Mapper table1Mapper; @Autowired private Table2Mapper table2Mapper; @Transactional public void updateCode(String oldCode, String newCode) { // 先更新 table1 中的编码字段 int result1 = table1Mapper.updateCode(oldCode, newCode); if (result1 != 1) { throw new RuntimeException("更新 table1 失败"); } // 再更新 table2 中的编码字段 int result2 = table2Mapper.updateCode(oldCode, newCode); if (result2 != 1) { throw new RuntimeException("更新 table2 失败"); } } } ``` 在上述代码中,我们使用 `@Transactional` 注解来表示该方法是一个事务,当其中任何一个更新操作失败时,都会将整个事务回滚。 3. 最后,在你的 Controller 层中调用该 Service 方法即可完成编码的修改。例如: ```java @RestController public class MyController { @Autowired private MyService myService; @PostMapping("/updateCode") public void updateCode(@RequestParam("oldCode") String oldCode, @RequestParam("newCode") String newCode) { myService.updateCode(oldCode, newCode); } } ``` 在上述代码中,我们使用 `@PostMapping` 注解来表示该方法处理 POST 请求,并使用 `@RequestParam` 注解来获取请求参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值