原则上一条SQL只更新一条数据库操作,但有时需要批量操作数据,特别是一些DML语句,在操作数据库时,数据库会报出异常,不允许混合语句,此时需要额外配置进行兼容。
例如:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 purchase_instrument_bill_detail ??
? ? ? ? ? ? ? ? ?SET out_count = '1',
' at line 8
Caused by: java.sql.SQLException: sql injection violation, multi-statement not
allowcom.alibaba.druid.wall.WallFilter.check(WallFilter.java:714)
atcom.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:240)
atcom.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:448)
atcom.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:928)
解决方案:
- 数据库连接加参数
- 连接池需要配置
1. 数据库连接加参数
添加参数allowMultiQueries=true
可解决数据库连接层面的异常问题,指定连接数据库时,可执行混合SQL。
参考连接配置: jdbc:mysql://\({datasource.host}:\){datasource.port}/${datasource.name}?relaxAutoCommit=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&useSSL=false&allowMultiQueries=true
2. 连接池需要配置
如果使用的数据库连接池是Druid,则需要额外配置参数。其他种类连接池,如C3P0,DBCP等,尚未考证。
## 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙,此处去除防火墙
spring.datasource.druid.filters=config,stat,slf4j
## 配置过滤器wall的参数
spring.datasource.druid.filter.wall.config.use-allow=false
spring.datasource.druid.filter.wall.config.multi-statement-allow=true
wall是com.alibaba.druid.wall.WallFilter的简称,提供sql的检查和过滤等功能,默认这里会对混合SQL进行拦截,此处为了执行大SQL,可关闭防火墙功能。(有SQL注入风险,谨慎使用)
附上一个MyBatis的xml脚本demo:
<update id="batchUpdateForRepay" parameterType="com.xxx.settle.credit.generate.domain.bo.RepayUpdateCreditInfoBO">
<foreach collection="list" index="index" item="item" separator=";">
update tb_credit_info
<trim prefix="set" suffixOverrides=",">
<if test="item.state != null">state = #{item.state},</if>
<if test="item.leftPrincipalAmount != null">left_principal = left_principal - #{item.leftPrincipalAmount},</if>
<if test="item.currentPeriodChange != null">current_period = current_period + #{item.currentPeriodChange},</if>
<if test="item.receivedPrincipalAmount != null">received_principal = received_principal + #{item.receivedPrincipalAmount},</if>
<if test="item.remark != null">remark = #{item.remark},</if>
</trim>
where product_id = #{item.productId} and credit_id = #{item.creditId}
</foreach>
</update>
原文地址:https://www.cnblogs.com/starmoon1994/p/10151722.html
时间: 2024-11-07 01:37:43