本文分为以下几个部分:
前言
验证过程
结论
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;
我们在用连接工具看看
所以我们在判断是否更新成功时,尽量和源码相同,采用判断返回结果 大于等于1 来判断,而不是单纯的判断是否等于0!
public static boolean retBool(Integer result) { return null != result && result >= 1; }