Mybatis 批量更新遇到的小問題

小問題

記一個開發過程中因爲小細節的遺漏而引發的 "莫名其妙",公司中有個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

再次調試,這時就可以正常執行了,數據得以更新成功,細節決定成敗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章