小問題
記一個開發過程中因為小細節的遺漏而引發的 "莫名其妙",公司中有個2B(to B)供應鏈項目,持久層用的是 JPA,這里我就不比較 JPA 和 Mybatis 的優劣了,但 JPA 對於多表關聯的系統和后期維護性真的是差。
由於是新功能的開發,查詢的功能中需要多字段的條件查詢,涉及到多張表的關聯操作。我試着用 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
再次調試,這時就可以正常執行了,數據得以更新成功,細節決定成敗。