zoukankan      html  css  js  c++  java
  • 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语句就会报出异常。

  • 相关阅读:
    js 数组扁平
    leetcode 15 三数之和
    leetcode 1 两数之和
    编写一个自定义事件类,包含on/off/emit/once方法
    css常见双栏和三栏布局
    关于js中this指向的问题
    函数防抖和节流
    ie6 js报错汇总
    windows PHP配置随笔
    上传文件表单file,限制上传文件类型的方法--参数accept
  • 原文地址:https://www.cnblogs.com/songanwei/p/9120593.html
Copyright © 2011-2022 走看看