1. 程式人生 > 其它 >MP update不存在的資料返回值一定為零?

MP update不存在的資料返回值一定為零?

MP update不存在的資料返回值一定為零?

本文分為以下幾個部分:

前言

驗證過程

結論

前言

​ MP(mybatis-plus),在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生,增加了程式碼生成器、IService、BaseMapper等功能,方便我們日常 使用 (偷懶),CURD (Create、Retrieve、Update、Delete)是我們日常開發會碰到的,MP 的 Mapper 的 update 極大縮短了我們需要寫的程式碼(當然也可以使用IService的方法)。我們知道這個 update 方法會返回一個 int 型別的值,當我們更新不存在的資料時,返回值是多少呢?

驗證過程

使用SpringBoot專案,使用德魯伊多資料來源配置

配置了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);
}

第一次更新了一條資料,所以更新行數為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);
}

mysql同樣,第一次更新了一條資料,所以更新行數為1,第二次更新了沒有的資料,返回了 0

我們看一下原始碼,BaseMapper裡面update程式碼,看不到原始的程式碼,但是我們可以看一下ServiceImpl

檢視ServiceImpl的retBool方法,一直 ctrl+左鍵檢視呼叫的方法,最後我們會看到

/**
* 判斷資料庫操作是否成功
*
* @param result 資料庫操作返回影響條數
* @return boolean
*/
public static boolean retBool(Integer result) {
    return null != result && result >= 1;
}

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);
}

我們發現,當達夢正常更新的時候,返回的是更新的行數,但是當更新不存在的資料時,返回的卻是 -1,所以MP的作者用的是 大於等於1 來判斷是否更新成功,而不是 ==0;

我們在用連線工具看看

  • oracle, update rows = 0
  • mysql, update rows = 0
  • 達夢, update rows = -1

結論

所以我們在判斷是否更新成功時,儘量和原始碼相同,採用判斷返回結果 大於等於1 來判斷,而不是單純的判斷是否等於0!

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