MybatisPlus中updateById方法不能更新空值如何解决

发布时间:2022-08-11 11:29:51 作者:iii
来源:亿速云 阅读:1260

MybatisPlus中updateById方法不能更新空值如何解决

引言

MybatisPlus是Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,简化开发、提高效率。MybatisPlus提供了很多便捷的方法,其中updateById方法是一个非常常用的方法,用于根据主键更新记录。然而,在实际使用过程中,很多开发者发现updateById方法无法更新空值(null值),这给开发带来了一定的困扰。本文将详细探讨这个问题,并提供多种解决方案。

1. 问题描述

在使用MybatisPlus的updateById方法时,如果传入的实体对象中有属性为null,那么这些属性将不会被更新到数据库中。例如:

User user = new User();
user.setId(1L);
user.setName(null);
user.setAge(20);
userMapper.updateById(user);

在上述代码中,name字段被设置为null,但执行updateById方法后,数据库中的name字段并不会被更新为null,而是保持原来的值。

2. 问题原因

MybatisPlus的updateById方法默认使用的是UPDATE语句的SET子句,只会更新非null的字段。这是因为MybatisPlus在设计时,为了避免误操作,默认忽略了null值的字段更新。

具体来说,MybatisPlus在生成SQL语句时,会检查实体对象中的每个字段是否为null,如果为null,则不会将该字段包含在SET子句中。因此,null值的字段不会被更新。

3. 解决方案

针对updateById方法不能更新空值的问题,我们可以通过以下几种方式来解决。

3.1 使用UpdateWrapper

UpdateWrapper是MybatisPlus提供的一个用于构建更新条件的工具类。通过UpdateWrapper,我们可以手动指定需要更新的字段,包括null值的字段。

User user = new User();
user.setId(1L);
user.setName(null);
user.setAge(20);

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("name", user.getName())
             .set("age", user.getAge())
             .eq("id", user.getId());

userMapper.update(null, updateWrapper);

在上述代码中,我们使用UpdateWrapper手动指定了nameage字段的更新值,即使namenull,也会被更新到数据库中。

3.2 使用SqlInjector自定义SQL注入器

MybatisPlus允许我们通过自定义SqlInjector来扩展其功能。我们可以通过自定义SqlInjector来实现更新null值的功能。

首先,我们需要创建一个自定义的SqlInjector

public class CustomSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        methodList.add(new UpdateByIdWithNull());
        return methodList;
    }
}

然后,我们需要创建一个自定义的UpdateByIdWithNull方法:

public class UpdateByIdWithNull extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String sql = "<script>UPDATE %s %s WHERE %s=#{%s}</script>";
        String tableName = tableInfo.getTableName();
        String setSql = sqlSet(tableInfo);
        String keyProperty = tableInfo.getKeyProperty();
        String keyColumn = tableInfo.getKeyColumn();
        sql = String.format(sql, tableName, setSql, keyColumn, keyProperty);
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addUpdateMappedStatement(mapperClass, modelClass, "updateByIdWithNull", sqlSource);
    }

    private String sqlSet(TableInfo tableInfo) {
        StringBuilder setSql = new StringBuilder();
        setSql.append("<set>");
        tableInfo.getFieldList().forEach(field -> {
            String column = field.getColumn();
            String property = field.getProperty();
            setSql.append(column).append("=#{").append(property).append("},");
        });
        setSql.append("</set>");
        return setSql.toString();
    }
}

最后,我们需要将自定义的SqlInjector注册到MybatisPlus中:

@Bean
public CustomSqlInjector customSqlInjector() {
    return new CustomSqlInjector();
}

通过这种方式,我们可以实现一个updateByIdWithNull方法,该方法可以更新null值的字段。

3.3 使用@TableField注解的updateStrategy属性

MybatisPlus提供了@TableField注解,用于配置字段的相关属性。其中,updateStrategy属性可以控制字段的更新策略。

我们可以通过设置updateStrategyFieldStrategy.IGNORED来忽略字段的null值检查,从而实现更新null值的功能。

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    @TableField(updateStrategy = FieldStrategy.IGNORED)
    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将name字段的updateStrategy设置为FieldStrategy.IGNORED,这样即使namenull,也会被更新到数据库中。

3.4 使用@SqlParser注解

MybatisPlus提供了@SqlParser注解,用于控制SQL解析的行为。我们可以通过设置@SqlParser注解的filter属性为true,来忽略null值的字段更新。

@SqlParser(filter = true)
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将User类的@SqlParser注解的filter属性设置为true,这样在执行updateById方法时,null值的字段也会被更新到数据库中。

3.5 使用LambdaUpdateWrapper

LambdaUpdateWrapper是MybatisPlus提供的另一种构建更新条件的方式,它支持Lambda表达式,使用起来更加简洁。

User user = new User();
user.setId(1L);
user.setName(null);
user.setAge(20);

LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(User::getName, user.getName())
             .set(User::getAge, user.getAge())
             .eq(User::getId, user.getId());

userMapper.update(null, updateWrapper);

在上述代码中,我们使用LambdaUpdateWrapper手动指定了nameage字段的更新值,即使namenull,也会被更新到数据库中。

3.6 使用@TableField注解的fill属性

MybatisPlus提供了@TableField注解的fill属性,用于控制字段的自动填充行为。我们可以通过设置fill属性为FieldFill.UPDATE,来在更新时自动填充字段。

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    @TableField(fill = FieldFill.UPDATE)
    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将name字段的fill属性设置为FieldFill.UPDATE,这样在执行updateById方法时,name字段会被自动填充为null,从而实现更新null值的功能。

3.7 使用@Version注解

MybatisPlus提供了@Version注解,用于实现乐观锁功能。我们可以通过设置@Version注解,来控制字段的更新行为。

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    @Version
    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将name字段设置为@Version注解,这样在执行updateById方法时,name字段会被更新为null,从而实现更新null值的功能。

3.8 使用@TableLogic注解

MybatisPlus提供了@TableLogic注解,用于实现逻辑删除功能。我们可以通过设置@TableLogic注解,来控制字段的更新行为。

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    @TableLogic
    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将name字段设置为@TableLogic注解,这样在执行updateById方法时,name字段会被更新为null,从而实现更新null值的功能。

3.9 使用@TableId注解

MybatisPlus提供了@TableId注解,用于指定主键字段。我们可以通过设置@TableId注解,来控制字段的更新行为。

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    @TableId(type = IdType.INPUT)
    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将name字段设置为@TableId注解,这样在执行updateById方法时,name字段会被更新为null,从而实现更新null值的功能。

3.10 使用@TableName注解

MybatisPlus提供了@TableName注解,用于指定表名。我们可以通过设置@TableName注解,来控制字段的更新行为。

@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

    private String name;

    private Integer age;

    // getters and setters
}

在上述代码中,我们将User类设置为@TableName注解,这样在执行updateById方法时,name字段会被更新为null,从而实现更新null值的功能。

4. 总结

MybatisPlus的updateById方法默认不能更新null值的字段,这给开发带来了一定的困扰。本文详细探讨了这个问题,并提供了多种解决方案,包括使用UpdateWrapper、自定义SqlInjector、使用@TableField注解的updateStrategy属性、使用@SqlParser注解、使用LambdaUpdateWrapper、使用@TableField注解的fill属性、使用@Version注解、使用@TableLogic注解、使用@TableId注解和使用@TableName注解。开发者可以根据实际需求选择合适的解决方案,以实现更新null值的功能。

5. 参考文档

6. 结语

MybatisPlus是一个非常强大的ORM框架,它简化了Mybatis的使用,提高了开发效率。然而,在实际使用过程中,我们可能会遇到一些问题,比如updateById方法不能更新null值的字段。通过本文的介绍,相信读者已经掌握了多种解决这个问题的方法。希望本文能够帮助读者更好地使用MybatisPlus,提高开发效率。

推荐阅读:
  1. 在python3中检测空值的方法
  2. python表示空值的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatisplus updatebyid

上一篇:python-memcached在python3.8环境中报SyntaxWarning如何修复

下一篇:element中el-cascader如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》