环境介绍:我的项目使用了 Java+ Mybatis,数据库是 MySQL
实现目标:传入一个对象更新表数据,如果存在该主键的值则修改,没有的话则新增/插入
下面是Mybatis 的 xml 文件中的代码:
parameterType="com.xdf.femisnsb.model.OrderDetail">
insert INTO orderdetail
id,
mainid,
ordercode,
goodsname,
#{id,jdbcType=INTEGER},
#{mainid,jdbcType=INTEGER},
#{ordercode,jdbcType=VARCHAR},
#{goodsname,jdbcType=VARCHAR},
ON DUPLICATE KEY UPDATE
mainid = #{mainid,jdbcType=INTEGER},
ordercode = #{ordercode,jdbcType=VARCHAR},
goodsname = #{goodsname,jdbcType=VARCHAR},
执行测试语句前的数据如下图:(注意看 id=14 的行,测试语句会修改该行)
使用 Postman 测试 post 请求如下图:
看上图,用来测试的 json 对象是:{"id":14,"mainid":"1","ordercode":"chanchaw01","goodsname":null}
那么根据 Mybatis 的配置,会修改 id=14 的行的字段 ordercode 为 chanchaw01,但是不会修改字段 goodsname ,不过请看执行后的结果:
结果和预期不一致,为什么字段 goodsname 被修改了呢??
在 Java 中打印出了执行SQL
JDBC Connection [[email protected]] will not be managed by Spring
==> Preparing: insert INTO orderdetail ( id, mainid, ordercode ) values ( ?, ?, ? ) ON DUPLICATE KEY UPDATE mainid = ?, ordercode = ?, goodsname = ?
==> Parameters: 14(Integer), 1(Integer), chanchaw03(String), 1(Integer), chanchaw03(String), null
<== Updates: 2
Closing non transactional SqlSession [[email protected]]
Creating a new SqlSession
SqlSession [[email protected]] was not registered for synchronization because synchronization is not active
JDBC Connection [[email protected]] will not be managed by Spring
==> Preparing: insert INTO orderdetail ( id, mainid, ordercode ) values ( ?, ?, ? ) ON DUPLICATE KEY UPDATE mainid = ?, ordercode = ?, goodsname = ?
==> Parameters: 14(Integer), 1(Integer), chanchaw01(String), 1(Integer), chanchaw01(String), null
<== Updates: 2
Closing non transactional SqlSession [[email protected]]
看上面 console 打印的 SQL 语句,inser into 部分判断到 goodsname 是 null ,所以没有拼接该字段最终形成 insert INTO orderdetail ( id, mainid, ordercode ) values ( ?, ?, ? ) ,但是后面的 UPDATE 没有检测到 null ,导致形成了 SQL :UPDATE mainid = ?, ordercode = ?, goodsname = ? 最终字段 goodsname 被修改为了 null,这是什么问题?是我 xml 文件中写的不对?
有必要的话:QQ = 4092223171
回答
你试下
ON DUPLICATE KEY UPDATE
mainid = VALUES(mainid),
ordercode = VALUES(ordercode),
goodsname = VALUES(goodsname),