mybatis-plus更新问题 全量更新、只更新部分属性

项目:前端vue+后台java项目

数据库:默认是null,不是""

遇到的问题:使用elementUI的下拉框、treeSelect等控件删除一个对象的某些属性,之后无法成功更新“删除”掉这些数据

mybatis-plus更新问题 全量更新、只更新部分属性

mybatis默认更新规则是不更新属性为null的属性的。

一般情况下遇到的一个问题就是:只能改属性,删不掉属性。

从安全、性能角度考虑确实需要这样,但是如果一张表有多重数据入口,比如可以在多个页面操作修改含有同一个表的数据,就必须得查出来所有字段,会影响一部分性能,另外项目迭代、连表查询时也容易丢失某些字段导致更新时update成null

 

公司同事建议用不同的dto,然后给这些dto设置成默认全部更新去解决,楼主认为这样又会产生大量dto+mapper文件,服务层也需要注入大量类似名称的mapper,不算一个通用的方法

经过测试发现前端的这些空间点击clear会将属性变成undefined,前端传给后台时如果该属性是undefined就不会传递,但是如果是null就会传递

 

楼主的解决方案:前端封装控件,传递属性为null的属性,后台用jsonObect接收参数,通过updateWrapper和class反射机制产生一个updatewapper对象,之后mapper用wrapper去更新。

 

这里以treeSelect为例,在它的外部又套了一层,在这里对undefined的情况下进行判断,设置成了null。

mybatis-plus更新问题 全量更新、只更新部分属性

后台接口就这样写一下,更新部分用update方法代替了之前的

mybatis-plus更新问题 全量更新、只更新部分属性

生成wrapper的部分大概就是这样的遍历就行了,这里只有一种date情况,到未来可能有很多类型需要判断,到时候可以再用设计模式优化一下。

public static <E> UpdateWrapper setUpdateWrapper(E e, JSONObject object) throws Exception{
        UpdateWrapper<E> updateWrapper = new UpdateWrapper<E>();
        List<Field> fields = ReflectUtils.getAllFields(e.getClass(), new ArrayList<>());
        if (object != null) {
            String name=null;//java字段名
            String value=null;//数据库名
            for (Field field : fields) {
                boolean accessible = field.isAccessible();
                field.setAccessible(true);
                TableId tableId = field.getAnnotation(TableId.class);
                TableField tableField = field.getAnnotation(TableField.class);
                Class<?> type = field.getType();
                if (tableId!=null){
                    name = field.getName();
                    value = tableId.value();
                    if (object.containsKey(name)&&StringUtils.isNotBlank(value)){
                        if (type== Date.class){
                            Object o = object.get(name);
                            Long aLong = new Long(object.get(name).toString());
                            Date date = new Date(aLong);
                            String dateStr = DateUtil.dateFormat(date);
                            updateWrapper.set(value,dateStr);
                        }
                        updateWrapper.eq(value,object.get(name));
                    }
                }
                if (tableField!=null){
                    name = field.getName();
                    value = tableField.value();
                    if (object.containsKey(name)&&StringUtils.isNotBlank(value)){
                        if (type== Date.class){
                            Object o = object.get(name);
                            Long aLong = new Long(object.get(name).toString());
                            Date date = new Date(aLong);
                            String dateStr = DateUtil.dateFormat(date);
                            updateWrapper.set(value,dateStr);
                        }else{
                            updateWrapper.set(value,object.get(name));
                        }

                    }
                }
            }
        }
        return updateWrapper;
    }

 

上一篇:geoJSON中线要素MultiLineString类型与LineString类型的区别


下一篇:CSDN使用|如何找到自己关注到的人