mybatis-plus 的更新操作(个人资料更新) —— 前后端传参空值处理
文章目录
- updateById 方法
- update 方法
- 避免 null 和空字符串覆盖
- 思:不是说mybatis-plus更新的时候如果为null并不会更新数据库吗?但是我new的user里面本来就是null阿,就算copyProperties传null过去,不是一样吗?用updateById为什么更新后,数据库就变null了?
- 解决方案
updateById 方法
updateById 方法会根据实体对象的主键字段更新数据库中的记录。它会将实体对象中的所有字段(包括 null 值)写入数据库,覆盖原有的值。因此,如果实体对象中的某些字段为 null,这些 null 值会被写入数据库,覆盖原有的值。
update 方法
update 方法需要一个实体对象和一个条件(如 QueryWrapper 或 LambdaUpdateWrapper)。它只会更新实体对象中非 null 的字段。如果实体对象中的某些字段为 null,这些字段不会被更新,原有的值会保持不变。
避免 null 和空字符串覆盖
在调用 updateById 或 update 方法之前,确保实体对象中的字段值是有效的,或者过滤掉 null 和空字符串值。
思:不是说mybatis-plus更新的时候如果为null并不会更新数据库吗?但是我new的user里面本来就是null阿,就算copyProperties传null过去,不是一样吗?用updateById为什么更新后,数据库就变null了?
原因一: updateById
方法会根据实体对象的主键字段更新数据库中的记录。它会将实体对象中的所有字段(包括 null 值)写入数据库,覆盖原有的值
原因二: 前端传的不是null,比如说字符串传了空字符串,并非null,所以也会更新到数据库中
解决方案
方案一: 前端控制:
前端只发送需要更新的字段,减少不必要的字段更新,提高性能。
方案二: 后端处理:
由于 BeanUtils.copyProperties 不支持直接忽略空字符串(“”),你需要在后端手动处理这些空字符串,确保它们不会覆盖目标对象中的现有值。这可以通过在复制属性之前手动检查字段值来实现。
@Overridepublic UpdateUserResponse updateUser(UpdateUserRequest request) {String jwt = httpServletRequest.getHeader("token");Claims claims = JwtUtil.parse(jwt);String userIdStr = claims.getSubject();Long userId = Long.parseLong(userIdStr);// //通过token找到对应user
// //queryWrapper.eq("user_id", ) 中传入的 userId 的数据类型应该与数据库中 user_id 字段的类型一致。
// //MyBatis-Plus 在构建 SQL 查询时,会根据传入的参数类型生成相应的 SQL 语句。
// //在我的数据库表中,user_id 字段的类型是 bigint,在我的 Java 实体类中,user_id 字段应该对应为 Long 类型,以匹配数据库中的 bigint 类型。QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_id", userId);//注意://updateById 方法会根据实体对象的主键字段更新数据库中的记录。它会将实体对象中的所有字段(包括 null 值)写入数据库,覆盖原有的值。因此,如果实体对象中的某些字段为 null,这些 null 值会被写入数据库,覆盖原有的值。//update 方法需要一个实体对象和一个条件(如 QueryWrapper 或 LambdaUpdateWrapper)。// 它只会更新实体对象中非 null 的字段。// 如果实体对象中的某些字段为 null,这些字段不会被更新,原有的值会保持不变。User user = new User();if (request.getUserName() != null && !request.getUserName().isEmpty()) {user.setUserName(request.getUserName());}if (request.getPassword() != null && !request.getPassword().isEmpty()) {user.setPassword(request.getPassword());}if (request.getEmail() != null && !request.getEmail().isEmpty()) {user.setEmail(request.getEmail());}if (request.getPhone() != null && !request.getPhone().isEmpty()) {user.setPhone(request.getPhone());}if (request.getSignature() != null && !request.getSignature().isEmpty()) {user.setSignature(request.getSignature());}if (request.getGender() != -1) {user.setGender(request.getGender());}if (request.getStatus() != -1) {user.setStatus(request.getStatus());}//在实体类中,需要在主键属性上加上 @TableId 注解。// 使用 updateById 方法时,只需要传入一个实体对象,MyBatis-Plus 会自动更新这个实体中非空字段对应的数据库记录boolean isUpdate = this.update(user, queryWrapper);return new UpdateUserResponse().setUserId(userId).setUpdate(isUpdate);}}
嗯改了一下,都可以兼容
不修改的参数不传也可以,传空字符串也可以,传null也可以
然后像gender和status这种整数类型的如果要传然后不修改的话,传-1就可以