Mapstruct对象插入数据库某个字段总是为空或者赋值失败

MapStruct对象赋值失败:原因与解决方案,
本文讲述了在使用MapStruct进行对象映射时遇到的赋值失败问题,原因是源对象缺少get方法或目标对象缺少set方法。解决方案包括使用Lombok注解或自定义set/get方法,对于add开头的字段,作者采取了禁用的粗暴方法。

1、问题描述

使用mapstruct进行对象间赋值时出现了赋值失败的情况,即赋值后新对象里面的所有属性都是空值,点击查看class反编译的代码后发现没有调用set方法

2、问题分析

1、因为mapstruct的原理是通过调用get方法获取源对象的值,再调用set方法赋值给目标对象(如图),所以源对象需要有get方法,目标对象需要有set方法。检查发现是目标对象没有写set方法也没有使用lombok的@Data注解

3、解决方案

1、使用lombok的@Data注解或者@Setter和@Getter注解

2、手动编写set和get方法

4、典型问题

如果字段是add开头命名的字段,那么就无法赋值,

比如:addNum,如果字段是这样的,那么就总是null

解决方法:我用最粗暴的方法,直接不用这个了

在 MyBatis Plus 中,我们可以通过判断数据是否存在(根据 `id`)来决定是执行新增操作还是更新操作。你提到的“**当没有时增加,有时按接收到的字段更新**”可以理解为: - 如果传入的 JSON 对象中 **id 存在或为**,则执行插入(insert) - 如果 **id 存在且数据库中有对应记录**,则执行更新(update),并且只更新客户端传来的字段(即部分更新) --- ## ✅ 实现思路 1. 使用 `@RequestBody Map<String, Object>` 接收任意字段 2. 提取 `id` 字段判断是否需要新增或更新 3. 使用 `MyBatis Plus` 的 `update(Wrapper)` 和 `save(Entity)` 方法完成操作 4. 使用 `BeanUtils` 或 `MapStruct` 动态赋值(可选) --- ## ✅ 修改 Controller 层支持动态增改 ### 1. 新增依赖(如果你还没有) 确保你的项目中包含如下工具类库: ```xml <!-- Apache Commons BeanUtils --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.4</version> </dependency> <!-- 或者使用 MapStruct(推荐用于生产环境) --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.2.Final</version> </dependency> ``` --- ### 2. 修改 Controller 方法 #### ✅ 示例:新增或修改载具信息 ```java @ApiOperation("新增或更新载具信息") @PostMapping("/saveOrUpdate") @PreAuthorize("@el.check('container:edit')") public Response saveOrUpdate(@RequestBody Map<String, Object> payload) { log.info("【API】新增或更新载具信息,payload={}", payload); try { Long id = null; if (payload.containsKey("id")) { Object idObj = payload.get("id"); if (idObj instanceof Number) { id = ((Number) idObj).longValue(); } else if (idObj instanceof String) { id = Long.valueOf((String) idObj); } } if (id == null || id <= 0) { // 插入新记录 ContainerBasicInfo info = new ContainerBasicInfo(); org.apache.commons.beanutils.BeanUtils.populate(info, payload); boolean success = containerService.save(info); return success ? Response.success() : Response.fail("新增失败"); } else { // 更新已有记录(仅更新传入字段) ContainerBasicInfo existing = containerService.getById(id); if (existing == null) { return Response.fail("未找到该载具"); } // 只更新传入的字段 for (Map.Entry<String, Object> entry : payload.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if ("id".equals(key)) continue; // 跳过 id // 使用反射设置字段java.lang.reflect.Field field = ContainerBasicInfo.class.getDeclaredField(key); field.setAccessible(true); field.set(existing, value); } boolean success = containerService.updateById(existing); return success ? Response.success() : Response.fail("更新失败"); } } catch (Exception e) { log.error("保存载具信息失败", e); return Response.fail("操作失败:" + e.getMessage()); } } ``` --- ## ✅ 说明 | 特性 | 说明 | |------|------| | `@RequestBody Map<String, Object>` | 接收任意字段,实现灵活更新 | | `BeanUtils.populate()` | 将 map 自动映射到实体类字段 | | `Reflection` | 手动设置字段值,避免覆盖未传字段 | | `updateById()` | MyBatis Plus 提供的更新方法 | --- ## ✅ 更佳实践建议(进阶) - ✅ 使用 `MapStruct` 替代 `BeanUtils` 提高性能和类型安全 - ✅ 使用 DTO 模式封装请求体,再做字段过滤处理 - ✅ 使用 `UpdateWrapper` 实现更细粒度的字段更新控制 - ✅ 增加字段白名单校验,防止非法字段被写入 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值