java实现动态修改表数据,方便扩展
前言
业务中常见需要修改表格某个字段的需求,传统的实现方式需要每个字段编写接口,存在重复开发,效率低的问题。可以设计个批量修改的接口,实现自定义修改需要的字段。
核心代码
入参
@ApiModelProperty("主键")
@NotEmpty(message = "主键列表不能为空")
private List<Long> ids;
@ApiModelProperty("批量操作字段")
@NotNull(message = "更新字段不能为null")
private String updateFieldName;
@ApiModelProperty("批量操作值")
private Object updateFieldValue;
@ApiModelProperty(value = "批量操作类型,update/clear/append")
@NotNull(message = "批量操作类型不能为null")
private String batchType;
枚举类
@Getter
@AllArgsConstructor
public enum BatchUpdateBatchTypeEnum {
CLEAR("clear", "清除"),
UPDATE("update", "修改"),
APPEND("append", "追加"),
;
private String code;
private String msg;
//添加根据code获取枚举对象的方法
public static BatchUpdateBatchTypeEnum getByCode(String code) {
for (BatchUpdateBatchTypeEnum item : values()) {
if (item.getCode().equals(code)) {
return item;
}
}
return null;
}
}
修改方法
@Override
public void batchUpdate(BatchUpdateParam updateParam) throws NoSuchFieldException {
BatchUpdateBatchTypeEnum batchTypeEnum = BatchUpdateBatchTypeEnum .getByCode(updateParam.getBatchType());
if (batchTypeEnum == null) {
throw new RuntimeException("批量操作类型错误");
}
Object value = updateParam.getUpdateFieldValue();
boolean isList = false;
if (value instanceof List) {
isList = true;
if (batchTypeEnum == BatchUpdateBatchTypeEnum .UPDATE) {
value = JsonUtils.toJsonString(value);
}
} else if (batchTypeEnum == BatchUpdateBatchTypeEnum .APPEND) {
//数据类型不是列表,不允许append
throw new RuntimeException("数据类型不是列表,不允许append");
}
String fieldName = updateParam.getUpdateFieldName();
//这里用的mybatisPlus的方法,如果没有的话使用反射也可以,主要是判断字段是否存在的
ColumnCache columnCache = LambdaUtils.getColumnMap(IgShippingDemandDO.class).entrySet().stream().filter(e ->
e.getKey().equalsIgnoreCase(fieldName)).map(Map.Entry::getValue).findAny().orElse(null);
if (columnCache == null) {
throw new RuntimeException("字段不存在");
}
if (batchTypeEnum == BatchUpdateBatchTypeEnum .CLEAR) {
UpdateWrapper<UserDO> updateWrapper = new UpdateWrapper<UserDO>()
.in("id", updateParam.getIds())
.set(columnCache.getColumn(), null);
mapper.update(null, updateWrapper);
} else {
//update或者append校验参数类型是否都是list或者都不是
if ((isList && UserDO.class.getDeclaredField(fieldName).getType() != List.class)
|| (!isList && UserDO.class.getDeclaredField(fieldName).getType() == List.class)) {
throw new RuntimeException("数据类型错误");
}
if (batchTypeEnum == BatchUpdateBatchTypeEnum .UPDATE) {
UpdateWrapper<UserDO> updateWrapper = new UpdateWrapper<UserDO>()
.in("id", updateParam.getIds())
.set(columnCache.getColumn(), value);
mapper.update(null, updateWrapper);
} else if (batchTypeEnum == BatchUpdateBatchTypeEnum .APPEND) {
List<UserDO> userDOS = new ArrayList<>();
//追加数据,如何实现
for (Long batchId : updateParam.getIds()) {
UserDO userDO = mapper.selectById(batchId);
if (userDO == null) {
continue;
}
//根据columnCache.getColumn()反射获取属性点值,并且将list的值合并进去,并且去重
try {
Field field = UserDO.class.getDeclaredField(fieldName);
field.setAccessible(true); // 确保可以访问私有字段
List<Object> list = getObjectList(field.get(userDO), value);
UserDO userDOUpdate = new UserDO();
userDOUpdate.setId(userDOUpdate.getId());
//根据反射设置fieldName的值
field.set(userDOUpdate, list);
userDOS.add(userDOUpdate );
} catch (Exception e) {
throw new RuntimeException("字段错误");
}
}
mapper.updateBatch(userDOS);
}
}
}
@Nullable
private static List<Object> getObjectList(Object object, Object value) {
if (object == null) {
return (List<Object>) value;
}
List<Object> list = (List<Object>)object;
//将value的值合并进去,并且去重
List<Object> valueList = (List<Object>) value;
for (Object o : valueList) {
if (!list.contains(o)) {
list.add(o);
}
}
return list;
}
前端界面
要更改的字段是列表的时候,可以追加的时候才展示追加字段值,不是列表的时候不展示
总结
通过优化更改接口,只需要前段传入要更改的字段和值,即可实现表格任意字段的更改,减少了开发量,提高了开发效率。