mybatis 一次執行多條SQL MySql+Mybatis+Druid之SqlException:sql injection violation, multi-statement not allow


如果用JDBC

jdbc.jdbcUrl=jdbc:mysql://127.0.0.1:3306/database?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true

 

如果用阿里巴巴的數據源

 

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

異常一:

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

提示:違反sql注入:多聲明不被允許

以下是棧異常輸出:

 

[java]  view plain  copy
 
  1. Caused by: java.sql.SQLException: sql injection violation, multi-statement not allow : UPDATE  
  2.             t_single_project_score  
  3.              SET update_time=now() ,  
  4.             is_delete = 1 ,  
  5.             operator =?   
  6.             WHERE  
  7.                
  8.                 student_id IN (?)  
  9.                
  10.                
  11.                 AND school_year IN(  
  12.                 ?  
  13.                 )  
  14.                
  15.             AND is_delete = 0  
  16.          ;   
  17.             UPDATE  
  18.             t_single_project_score  
  19.              SET update_time=now() ,  
  20.             is_delete = 1 ,  
  21.             operator =?   
  22.             WHERE  
  23.                
  24.                 student_id IN (?)  
  25.                
  26.                
  27.                 AND school_year IN(  
  28.                 ?  
  29.                 )  
  30.                
  31.             AND is_delete = 0  
  32.         at com.alibaba.druid.wall.WallFilter.checkInternal(WallFilter.java:800)  
  33.     at com.alibaba.druid.wall.WallFilter.connection_prepareStatement(WallFilter.java:251)  
  34.     at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)  
  35.     at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929)  
  36.     at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)  
  37.     at com.alibaba.druid.filter.FilterAdapter.connection_prepareStatement(FilterAdapter.java:929)  
  38.     at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:122)  
  39.     at com.alibaba.druid.filter.FilterChainImpl.connection_prepareStatement(FilterChainImpl.java:473)  
  40.     at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.prepareStatement(ConnectionProxyImpl.java:342)  
  41.     at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:349)  
  42.     at com.p6spy.engine.wrapper.ConnectionWrapper.prepareStatement(ConnectionWrapper.java:119)  
  43.     at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87)  
  44.     at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)  
  45.     at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59)  
  46.     at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85)  
  47.     at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)  
  48.     at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)  
  49.     at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)  
  50.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  51.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
  52.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  53.     at java.lang.reflect.Method.invoke(Method.java:483)  
  54.     at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)  
  55.     at com.sun.proxy.$Proxy44.update(Unknown Source)  
  56.     at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)  
  57.     at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:213)  
  58.     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  59.     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
  60.     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
  61.     at java.lang.reflect.Method.invoke(Method.java:483)  
  62.     at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)  
  63.     ... 52 more  

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

 

在輸出的日志里,找到關鍵信息:

[java]  view plain  copy
 
  1. 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即可

 

[html]  view plain  copy
 
  1. <!--在spring-db.xml的wall-filter中添加config,修改后如下-->  
  2.   
  3.     <bean id="wall-filter" class="com.alibaba.druid.wall.WallFilter">  
  4.         <property name="dbType" value="mysql"/>  
  5.         <!--<property name="config" ref="wall-config"/>-->  
  6.     </bean>  
  7.   
  8.     <!--解決mybatis與druid集成后,wallFilter sql注入異常-->  
  9.     <bean id="wall-config" class="com.alibaba.druid.wall.WallConfig">  
  10.         <property name="multiStatementAllow" value="true"/>  
  11.     </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

 

[java]  view plain  copy
 
  1. 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   
  2.         'UPDATE  
  3.                     t_single_project_score  
  4.                      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語句就會報出異常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM