1. 程式人生 > >MySql+Mybatis+Druid之SqlException:sql injection violation, multi-statement not allow

MySql+Mybatis+Druid之SqlException:sql injection violation, multi-statement not allow

接上一篇部落格:資料庫優化之MyBatis批量刪除、更新

Druid是阿里巴巴,開發的一個數據庫連線池工具,經歷過多次雙十一的洗禮,它的效能已經能夠滿足國內大多數專案的需求。

異常一:

專案中啟用Druid的統計管理,在執行批量修改時:提示Error updating database.  Cause: java.sql.SQLException: sql injection violation, multi-statement not allow 。

提示:違反sql注入:多宣告不被允許

以下是棧異常輸出:

Caused by: java.sql.SQLException: sql injection violation, multi-statement not allow : UPDATE
            t_single_project_score
             SET update_time=now() ,
            is_delete = 1 ,
            operator =? 
            WHERE
             
                student_id IN (?)
             
             
                AND school_year IN(
                ?
                )
             
            AND is_delete = 0
         ; 
            UPDATE
            t_single_project_score
             SET update_time=now() ,
            is_delete = 1 ,
            operator =? 
            WHERE
             
                student_id IN (?)
             
             
                AND school_year IN(
                ?
                )
             
            AND is_delete = 0
        at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:800)
	at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:251)
	at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)
	at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929)
	at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)
	at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929)
	at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)
	at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)
	at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)
	at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:349)
	at com.p6spy.engine.wrapper.ConnectionWrapper.prepareStatement(ConnectionWrapper.java:119)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59)
	at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
	at com.sun.proxy.$Proxy44.update(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:213)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
	... 52 more

通過異常棧輸出出現異常如何分析解決?


在輸出的日誌裡,找到關鍵資訊:
at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:800)

這是在spring-db.xml的wall-filter這個 bean中報出的異常:


在這個WallFilter找到checkInternal方法,就會看到提示的錯誤資訊前半部分:sql injection violation


檢視check()方法-->checkInternal()方法



找到異常後半段:multi-statement not allow。造成列印這個異常訊息的原因是config.ismultiStatementAllow()為false




解決方法:把multiStatementAllow修改成true即可

<!--在spring-db.xml的wall-filter中新增config,修改後如下-->

    <bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">
        <property name="dbType" value="mysql"/>
        <!--<property name="config" ref="wall-config"/>-->
    </bean>

    <!--解決mybatis與druid整合後,wallFilter sql注入異常-->
    <bean id="wall-config" class="com.alibaba.druid.wall.WallConfig">
        <property name="multiStatementAllow" value="true"/>
    </bean>

瞭解wall-filter: 通過官方文件配置

異常二: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

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
		            t_single_project_score
		             SET update_time=now() , '

參考:

sql關鍵字衝突】https://www.cnblogs.com/zzxbest/archive/2011/09/22/2185029.html

sql關鍵字衝突】http://blog.csdn.net/qq_34698126/article/details/53128746

解決方法:這個問題一直報sql語法問題,刪除wall-filter的bean和wall-config的bean,同時在jdbc上加上allowMultiQueries=true&,問題得到了解決。

分析:wall-filter會攔截多次宣告請求的迴圈sql語句,即使設定為true,還會檢測到sql語句間的';'分號會視為sql已經結束,所以有sql迴圈,第二個sql語句就會報出異常。


以上不是最終的解決方案,希望遇到過這個問題的親們,可以多多留言與小編交流。

祝好運