小问题

记一个开发过程中因为小细节的遗漏而引发的 "莫名其妙",公司中有个2B(to B)供应链项目,持久层用的是 JPA,这里我就不吐槽 JPA 了,这种 SQL 嵌入在代码里的方式真的不够简洁。

由于是新功能的开发,查询的功能中需要多字段的条件查询,涉及到多张表的关联操作。我试着用 JPA 来写,发现写的很头疼,于是干脆来个改造,将 Mybatis 引入到了项目中,自己掌控 SQL 的感觉还是蛮好的,而且 SQL 和业务代码分离。

报错了

查询,插入,删除,更新这些功能都还好,但是在一次需要批量更新的时候报错了,提示我 SQL语法错误。

Mapper接口的代码如下

@Repository
public interface BasCustomerReservationOrderItemMapper {
void UpdateBatchByIds(@Param("list") List<BasCustomerReservationOrderItem> basCustomerReservationOrderItemList);
}

SQL 映射 xml 文件内容如下

<update id="UpdateBatchByIds">
<foreach collection="list" item="record" index="index" open="" close="" separator=";">
update bas_customer_reservation_order_item
<set>
<if test="record.artno != null">
artno = #{record.artno,jdbcType=VARCHAR},
</if>
<if test="record.quantity != null">
quantity = #{record.quantity,jdbcType=DECIMAL},
</if>
<if test="record.sort != null">
sort = #{record.sort,jdbcType=INTEGER},
</if>
<if test="record.unit != null">
unit = #{record.unit,jdbcType=VARCHAR},
</if>
<if test="record.createBy != null">
create_by = #{record.createBy,jdbcType=VARCHAR},
</if>
<if test="record.createDate != null">
create_date = #{record.createDate,jdbcType=TIMESTAMP},
</if>
<if test="record.updateBy != null">
update_by = #{record.updateBy,jdbcType=VARCHAR},
</if>
<if test="record.updateDate != null">
update_date = #{record.updateDate,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{record.id,jdbcType=BIGINT}
</foreach>
</update>

这个批量更新语句很简单,但是执行的时候确总是报语法错误,报错信息如下

### SQL: update bas_customer_reservation_order_item        SET artno = ?,                             quantity = ?,                             sort = ?,                             unit = ?,                                               update_by = ?,                             update_date = ?        where id = ?      ;        update bas_customer_reservation_order_item        SET artno = ?,                             quantity = ?,                             sort = ?,                             unit = ?,                                               update_by = ?,                             update_date = ?        where id = ?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update bas_customer_reservation_order_item
SET artno = '100014',
' at line 22
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update bas_customer_reservation_order_item
SET artno = '100014',
' at line 22

字段类型,中英文符号,……,我全部检查了一遍都没发现错误,按照提示的line 22那里反复检查也确实没有错误呀。

原来如此

报错信息误导了我,导致我一直纠结在 SQL 语法那块,后来突然智慧之光一闪,单个的查询更新都没问题,只是这个批量处理的时候有问题,是不是不支持批量的呢?

通过查询相关文档后发现,原来如此

Mybatis 映射文件中的 sql 语句默认是不支持以" ; " 结尾的,也就是不支持多条 sql 语句的执行。如果要支持这种语句,需要在连接 mysql 的 url 上加 &allowMultiQueries=true 这个才可以执行。

所以只需要在application.yml的数据源连接配置的地方加上&allowMultiQueries=true即可

spring:
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true
type: com.alibaba.druid.pool.DruidDataSource
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver

再次调试,这时就可以正常执行了,数据得以更新成功,细节决定成败。

Mybatis 批量更新遇到的小问题的更多相关文章

  1. mybatis批量更新报错badsql

    mybatis批量更新时语法写的都对,但是报错,需要在连接上面加上allowMultiQueries=true 示例:jdbc:MySQL://192.168.1.236:3306/test?useU ...

  2. mybatis批量更新update-设置多个字段值 报错 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

    mybatis批量更新update-设置多个字段值 2016年08月01日 12:49:26 姚一号 阅读数:29539 标签: mysql mybatis批量更新批量更新allowMultiQuer ...

  3. Mybatis批量更新<转>

    Mybatis批量更新 批量操作就不进行赘述了.减少服务器与数据库之间的交互.网上有很多关于批量插入还有批量删除的帖子.但是批量更新却没有详细的解决方案. 实现目标 这里主要讲的是1张table中.根 ...

  4. Mybatis批量更新详解

    转:http://www.cnblogs.com/winkey4986/p/3915151.html Mybatis批量更新 批量操作就不进行赘述了.减少服务器与数据库之间的交互.网上有很多关于批量插 ...

  5. mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样

    Mybatis批量更新数据 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样 mybatis批 ...

  6. mybatis批量更新策略

    我们知道循环中操作db会导致连接数满,严重影响数据库性能.所以在对db进行DQL与DML时,根据业务逻辑尽量批量操作,这里我们介绍下使用mybatis批量更新mysql的两种方式. 方式一: < ...

  7. Mybatis批量更新数据库与批量插入数据库(以oracle为例)

    一.批量更新 1.普通写法(一条记录update一次,性能比较差,容易造成阻塞.不建议使用) <update id="updateBatch" parameterType=& ...

  8. mybatis 批量更新 Parameter '__frch_item_0' not found. Available parameters are [list]

    一次在做批量更新数据的时候报错 Parameter '__frch_item_0' not found. Available parameters are [list] 记过反复查找,最后才发现是一个 ...

  9. MyBatis批量更新

    逐条更新 这种方式显然是最简单,也最不容易出错的,即便出错也只是影响到当条出错的数据,而且可以对每条数据都比较可控. 代码 updateBatch(List<MyData> datas){ ...

随机推荐

  1. K-DTree入门

    \(K-D Tree\),一种用来维护\(K\)维数据的数据结构.常用于维护各种高维的数据,或者是邻近搜索等.从另一种意义上说,实际上就是高维的二叉搜索树.对于一些常见的问题,如\(k\)远点对.三位 ...

  2. 硬盘安装Linux

    准备材料:U盘.Linux镜像.UltraISO 1.下载安装UltraISO, 2.打开系统镜像 打开后我们就可以在左边侧栏看到镜像的内容 3.插入U盘,点击:启动->写入光盘映像->选 ...

  3. 证明RSA算法在明文和公私钥中N不互质情况下仍然成立

    关于RSA的基础过程介绍 下文中的 k 代表自然数常数,不同句子,公式中不一定代表同一个数 之前接触RSA,没有过多的思考证明过程,今天有感而发,推到了一遍 假设公钥 (e, N) , 私钥 (d, ...

  4. 版本控制系统之基于httpd搭建私有git仓库

    在上一篇博客中,我们主要聊到了git的基本工作原理和一些常用的git命令的使用:回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13787701.html:今天我 ...

  5. 让我们创建屏幕- Android UI布局和控件

    下载LifeCycleTest.zip - 278.9 KB 下载ViewAndLayoutLessons_-_Base.zip - 1.2 MB 下载ViewAndLayoutLessons_-_C ...

  6. client: c#+protobuf, server: golang+protobuf

    前段时间看到一篇博文<可在广域网部署运行的即时通讯系统 -- GGTalk总览(附源码下载)>,他是用C#实现的即时通讯系统,功能强大,界面漂亮. 就想用golang重写服务端,把代码下载 ...

  7. Git 看这一篇就够了

    上一篇讲 Git 的文章发出来没想到效果特别好,很多读者都要求继续深入的写. 那今天齐姐简单讲下 Git 的实现原理,知其所以然才能知其然:并且梳理了日常最常用的 12 个命令,分为三大类分享给你. ...

  8. shell脚本获取随机数

    $RANDOM系统变量 在bash中,支持$RANDOM系统变量,范围是 [0, 32767] #!/bin/bash set -e randN() { local N=$1 echo $(($RAN ...

  9. Go 安装配置golint

    原文链接:http://zhoubotong.site/post/3.html一. Golint介绍 Golint 是一个源码检测工具用于检测代码规范 Golint 不同于gofmt, Gofmt用于 ...

  10. 趣谈多线程(Python版)

    温馨提示:本文篇幅较长,建议读者耐心阅读,本文中的代码经过笔者精心构思,可以复制过去运行一下,观察输出结果,所有代码在python3.5.0中测试通过. 文章目录 What is 多线程? Why w ...