zoukankan      html  css  js  c++  java
  • springboot使用mybatis-plus表单更新null值问题通用解决方案

    问题背景

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

    单个解决方案

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

    通用解决方法

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

    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

        @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

    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 加入到配置中去

    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
            resolvers.add(new BaseModelMethodArgumentResolver());
        }
    }

    进行自定义UpdateWrapper构造

     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忽略注解的字段可以优化,反射可以应用初始化时扫描加入缓存进行优化

  • 相关阅读:
    随手记
    boost::asio::udp 异步
    boost::asio::tcp 异步
    boost::asio::tcp 同步
    QML::MouseArea
    boost::concurrent::sync_queue
    std::chrono::时钟
    数据结构::队列
    数据结构::栈
    数据结构::线性表
  • 原文地址:https://www.cnblogs.com/yanpeng19940119/p/12541852.html
Copyright © 2011-2022 走看看