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;
}
PS:同理delete操作返回值也和update一樣,但是不建議用delete方法,能用邏輯刪除就少使用物理刪除。