Mybatis-Plus update不存在的数据返回值一定为零?

MP update不存在的数据返回值一定为零?

本文分为以下几个部分:

前言

验证过程

结论

前言

​ MP(mybatis-plus),在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生,增加了代码生成器、IService、BaseMapper等功能,方便我们日常 使用 (偷懒),CURD (Create、Retrieve、Update、Delete)是我们日常开发会碰到的,MP 的 Mapper 的 update 极大缩短了我们需要写的代码(当然也可以使用IService的方法)。我们知道这个 update 方法会返回一个 int 类型的值,当我们更新不存在的数据时,返回值是多少呢?

验证过程

使用SpringBoot项目,使用德鲁伊多数据源配置

1

配置了Oracle(常用)、MySql(常用)、达梦安可)分别进行测试,

在三个数据库分别建立三张表

--ORACLE
create table TEST_ORACLE(
  ID VARCHAR2(32) PRIMARY KEY,
  VALUE VARCHAR2(32)
)

--MYSQL
create table TEST_MYSQL(
  ID VARCHAR(32) primary key,
  VALUE VARCHAR(32)
)

--达梦
create table TEST_DM(
  ID VARCHAR2(32) PRIMARY KEY,
  VALUE VARCHAR2(32)
)
--分别插入 '1' '1' 数据,即 ID='1' VALUE='1'

创建三个实体类,及对应的Mapper,注意Mapper 应该extends BaseMapper,例如

//实体类
@TableName("TEST_ORACLE")
@Data
public class TestOracle {
    private String id;
    private String value;
}

//mapper
@Mapper
public interface TestOracleMapper extends BaseMapper<TestOracle> {
}

使用SpringBootTest来进行测试,先进行oracle的测试,第一次更新我们数据库ID='1'的数据,第二次更新不存在的数据,主要看第二次返回值

@Test
void testOracle() {
    log.info(oracleMapper.selectList(null)+"");

    UpdateWrapper<TestOracle> wrapper = new UpdateWrapper<>();
    wrapper.set("VALUE","2");
    wrapper.eq("ID","1");
    int updateNum = oracleMapper.update(null, wrapper);
    log.info("更新行数:"+updateNum);

    log.info(oracleMapper.selectList(null)+"");

    UpdateWrapper<TestOracle> wrapper2 = new UpdateWrapper<>();
    wrapper2.set("VALUE","2");
    wrapper2.eq("ID","BIN");
    int updateNum2 = oracleMapper.update(null, wrapper2);
    log.info("更新行数:"+updateNum2);
}

2

第一次更新了一条数据,所以更新行数为1,第二次更新了没有的数据,返回了 0 ,一条没更新,返回0感觉也很正常。

再测试一下Mysql

@Test
void testMysql() {
    log.info(mysqlMapper.selectList(null)+"");

    UpdateWrapper<TestMysql> wrapper = new UpdateWrapper<>();
    wrapper.set("VALUE","2");
    wrapper.eq("ID","1");
    int updateNum = mysqlMapper.update(null, wrapper);
    log.info("更新行数:"+updateNum);

    log.info(mysqlMapper.selectList(null)+"");

    UpdateWrapper<TestMysql> wrapper2 = new UpdateWrapper<>();
    wrapper2.set("VALUE","2");
    wrapper2.eq("ID","BIN");
    int updateNum2 = mysqlMapper.update(null, wrapper2);
    log.info("更新行数:"+updateNum2);
}

3

mysql同样,第一次更新了一条数据,所以更新行数为1,第二次更新了没有的数据,返回了 0

我们看一下源码,BaseMapper里面update代码,看不到原始的代码,但是我们可以看一下ServiceImpl

4

查看ServiceImpl的retBool方法,一直 ctrl+左键查看调用的方法,最后我们会看到

/**
* 判断数据库操作是否成功
*
* @param result 数据库操作返回影响条数
* @return boolean
*/
public static boolean retBool(Integer result) {
    return null != result && result >= 1;
}

5

result 就是刚才的返回值,其中有判断 大于等于1 然后判断为有更新状态,返回 true,注意这里判断的是 大于等于 1,而不是直接判断 等于0,难道还有小于 0 的?

我们刚才配置了三个数据源,现在测试一下达梦数据库

@Test
void testDm() {
    log.info(dmMapper.selectList(null)+"");

    UpdateWrapper<TestDm> wrapper = new UpdateWrapper<>();
    wrapper.set("VALUE","2");
    wrapper.eq("ID","1");
    int updateNum = dmMapper.update(null, wrapper);
    log.info("更新行数:"+updateNum);

    log.info(dmMapper.selectList(null)+"");

    UpdateWrapper<TestDm> wrapper2 = new UpdateWrapper<>();
    wrapper2.set("VALUE","2");
    wrapper2.eq("ID","BIN");
    int updateNum2 = dmMapper.update(null, wrapper2);
    log.info("更新行数:"+updateNum2);
}

6

我们发现,当达梦正常更新的时候,返回的是更新的行数,但是当更新不存在的数据时,返回的却是 -1,所以MP的作者用的是 大于等于1 来判断是否更新成功,而不是 ==0;

我们在用连接工具看看

  • oracle, update rows = 0

7

  • mysql, update rows = 0

8

  • 达梦, update rows = -1

9

结论

所以我们在判断是否更新成功时,尽量和源码相同,采用判断返回结果 大于等于1 来判断,而不是单纯的判断是否等于0!

public static boolean retBool(Integer result) {
    return null != result && result >= 1;
}

PS:同理delete操作返回值也和update一样,但是不建议用delete方法,能用逻辑删除就少使用物理删除。

posted @ 2021-06-28 22:58  抱糖果彡  阅读(6020)  评论(0编辑  收藏  举报