前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >springboot使用mybatis-plus表单更新null值问题通用解决方案

springboot使用mybatis-plus表单更新null值问题通用解决方案

作者头像
code2roc
发布2023-07-19 14:41:51
5640
发布2023-07-19 14:41:51
举报

问题背景

使用mybatis-plus进行数据库交互,默认开启null不更新设置,在新增数据后,编辑页面将字段值清除后(date类型,int类型,为避免默认值传入,model全部使用包装类型初始化为null)无法将null值更新至数据库

单个解决方案

通过UpdateWrapper的set方法强制字段为null值

通用解决方法

定义基础类BaseModel,增加属性updateFieldList,model继承此类

代码语言:javascript
复制
public class BaseModel {
    @TableField(exist = false)
    @JSONField(serialize = false)
    private List<String> updateFieldList;

    public List<String> getUpdateFieldList() {
        return updateFieldList;
    }

    public void setUpdateFieldList(List<String> updateFieldList) {
        this.updateFieldList = updateFieldList;
    }
}

自定自定义注解UpdateRequestBody替代RequestBody

代码语言:javascript
复制
	@ResponseBody
	@PostMapping("/update")
	public Object update(@UpdateRequestBody AccountDO entity) {
		Result result = null;
		try {
			accountService.update(entity);
			result = Result.okResult();
		} catch (Exception e) {
			result = Result.errorResult();
		}
		return result;
	}

	@ResponseBody
	@PostMapping("/batchUpdate")
	public Object batchUpdate(@UpdateRequestBody List<AccountDO> entityList) {
		Result result = null;
		try {
			accountService.batchUpdate(entityList);
			result = Result.okResult();
		} catch (Exception e) {
			result = Result.errorResult();
		}
		return result;
	}

自定义HandlerMethodArgumentResolver对前台json至后台Model转换的拦截,需要对List类型的Model集合进行支持,获取前台提交json对应定义Model中有同名属性的,进行加入打待更新字段列表updateFieldList

代码语言:javascript
复制
public class BaseModelMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        if (methodParameter.hasParameterAnnotation(UpdateRequestBody.class)) {
            //集合
            if(List.class.isAssignableFrom(methodParameter.getParameterType())){
                ParameterizedType parameterizedType = (ParameterizedType) methodParameter.getGenericParameterType();
                Class clazz = (Class)parameterizedType.getActualTypeArguments()[0];
                //取出List中的真实对象类型
                if(BaseModel.class.isAssignableFrom(clazz)){
                    return true;
                }else{
                    return  false;
                }
            }else{
                //单个对象
                if(BaseModel.class.isAssignableFrom(methodParameter.getParameterType())){
                    return true;
                }else{
                    return false;
                }
            }
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        String body = "";
        try {
            HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
            body = CommonUtil.getBodyString(request);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(List.class.isAssignableFrom(methodParameter.getParameterType())){
            List resultList = new ArrayList();
            ParameterizedType parameterizedType = (ParameterizedType) methodParameter.getGenericParameterType();
            Class clazz = (Class)parameterizedType.getActualTypeArguments()[0];
            List<Field> fs = Arrays.asList(clazz.getDeclaredFields());
            JSONArray array = JSONArray.parseArray(body);
            for (Object temp:array) {
                JSONObject obj = JSONObject.parseObject(temp.toString());
                List<String> updateFieldList = new ArrayList<>();
                for (String key : obj.keySet()) {
                    for (Field filed : fs) {
                        if (key.toLowerCase().equals(filed.getName().toLowerCase())) {
                            updateFieldList.add(key.toLowerCase());
                            continue;
                        }
                    }
                }
                obj.put("updateFieldList",updateFieldList);
                resultList.add(obj);
            }
            return  JSONArray.parseArray(resultList.toString(),clazz);
        }else{
            Class clazz = methodParameter.getParameterType();
            List<String> updateFieldList = new ArrayList<>();
            List<Field> fs = Arrays.asList(clazz.getDeclaredFields());
            JSONObject obj = JSON.parseObject(body);
            for (String key : obj.keySet()) {
                for (Field filed : fs) {
                    if (key.toLowerCase().equals(filed.getName().toLowerCase())) {
                        updateFieldList.add(key.toLowerCase());
                        continue;
                    }
                }
            }
            obj.put("updateFieldList",updateFieldList);
            return JSON.parseObject(obj.toString(),clazz);
        }

    }
}

将自定义BaseModelMethodArgumentResolver 加入到配置中去

代码语言:javascript
复制
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new BaseModelMethodArgumentResolver());
    }
}

进行自定义UpdateWrapper构造

代码语言:javascript
复制
 public <T extends BaseModel>  UpdateWrapper getUpdateWrapper(T entity){
        UpdateWrapper<T> updateWrapper = new UpdateWrapper<T>();
        try{
           Class clazz = entity.getClass();
           List<Field> fs = Arrays.asList(clazz.getDeclaredFields());
           List<String> updateFieldList = entity.getUpdateFieldList();
           if(updateFieldList!=null){
               for (String updateFiled:updateFieldList ) {
                   for (Field field:fs) {
                       field.setAccessible(true);
                       if(field.getName().toLowerCase().equals(updateFiled)){
                           Object fieldValue = field.get(entity);
                           updateWrapper.set(fieldValue==null,field.getName(),null);
                           continue;
                       }
                   }
               }
           }
           return updateWrapper;
       }catch (Exception e){
           e.printStackTrace();
       }
        return updateWrapper;
    }

注:对标记TableField忽略注解的字段可以优化,反射可以应用初始化时扫描加入缓存进行优化

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题背景
  • 单个解决方案
  • 通用解决方法
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档