Mybatis-Plus 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;
}
PS:同理delete操作返回值也和update一样,但是不建议用delete方法,能用逻辑删除就少使用物理删除。