mysql批量执行sql报错解决

本文讲述了在SpringBoot项目集成Druid和Mybatis时,遇到批量删除报错的问题,原因是Druid的默认配置不允许多条SQL。文章详细介绍了如何检查数据库连接配置中的allowMultiQueries参数以及Druid的wallconfig设置,提供了配置示例和注意事项。
摘要由CSDN通过智能技术生成

起始原因

项目架构是SprigBoot + Mysql +Druid + Mybatis;
项目运行测试时,发现一个批量删除的小功能报错:sql injection violation, multi-statement not allow :
网上查询发现是Druid执行多条SQL时需要修改2项默认配置;

解决办法

解决办法分为两步,第一步检查数据库连接配置。第二步检查druid连接配置。
第一步检查数据库连接配置是否开启参数:
allowMultiQueries=true;

url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true

2、检查druid配置:
wallconfig.setMultiStatementAllow(true);
如图所示:
druid配置

项目配置示例

1、数据库连接配置:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      #最大连接数
      max-active: 50
      #初始化大小
      initial-size: 10
      #获取连接最大等待时间
      max-wait: 60000
      min-idle: 10
      #间隔多久检测一次需要关闭的空闲连接 毫秒
      time-between-eviction-runs-millis: 8000
      #连接在连接池中最小生存的时间 毫秒
      min-evictable-idle-time-millis: 50000
      validation-query: select 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      #是否开启PSCache,PSCache对支持游标的数据库性能提升巨大,oracle建议开启,mysql下建议关闭
      pool-prepared-statements: true
      max-open-prepared-statements: 50
      max-pool-prepared-statement-per-connection-size: 20
      web-stat-filter:
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
        url-pattern: /*
        enabled: true
      stat-view-servlet:
        enabled: true
        #白名单IP
        allow: 127.0.0.1,192.168.1.216,localhost
        #黑名单IP
        deny:
        #登录账号和密码
        login-username: admin
        login-password: admin
        #启用重置数据功能
        reset-enable: true
      #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,连接达梦数据库需要关闭wall配置
      filters: stat,wall
      connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

2、druid连接配置类:

@Configuration(proxyBeanMethods = false)
public class DataSourceConfig {

    @Bean(name = "dataSource")
    @Qualifier("dataSource")
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();

        try {
            // 开启SQL监控菜单功能,让druid进行SQL的执行统计
            // 开启SQL防火墙菜单功能
            druidDataSource.setFilters("stat");

        } catch (SQLException e) {
            e.printStackTrace();
        }

        //配置过滤器,执行多条sql
        List<Filter> filterList = new ArrayList<>();
        filterList.add(wallFilter());
        druidDataSource.setProxyFilters(filterList);
        return druidDataSource;
    }

    /**
     * 配置druid执行多条sql(批量执行),避免报sql注入异常
     * 链式配置,从下往上注入
     * @return 结果
     */
    public WallFilter wallFilter() {
        WallFilter wallFilter = new WallFilter();
        wallFilter.setConfig(wallConfig());
        return wallFilter;
    }

    private WallConfig wallConfig() {
        WallConfig wallconfig = new WallConfig();
        //允许一次执行多条语句
        wallconfig.setMultiStatementAllow(true);
        //允许非基本语句的其他语句
        wallconfig.setNoneBaseStatementAllow(true);
        return wallconfig;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> filterRegistrationBean() {
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<WebStatFilter>();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }


    /**
     * 配置druid管理页面的访问控制
     * 访问网址: http://127.0.0.1:8080/druid
     * @return
     */
    @Bean
    public ServletRegistrationBean<Servlet> druidServlet() {
      //  log.info("init Druid Servlet Configuration");
        ServletRegistrationBean<Servlet> servletRegistrationBean = new ServletRegistrationBean<>();
        servletRegistrationBean.setServlet(new StatViewServlet());  //配置一个拦截器
        servletRegistrationBean.addUrlMappings("/druid/*");    //指定拦截器只拦截druid管理页面的请求
        HashMap<String, String> initParam = new HashMap<String,String>();
        initParam.put("loginUsername", "admin");    //登录druid管理页面的用户名
        initParam.put("loginPassword", "admin");    //登录druid管理页面的密码
        initParam.put("resetEnable", "true");       //是否允许重置druid的统计信息
        initParam.put("allow", "");         //ip白名单,如果没有设置或为空,则表示允许所有访问
        servletRegistrationBean.setInitParameters(initParam);
        return servletRegistrationBean;
    }

注意事项

1、Druid配置的时候有一个大坑,就是不要同时配置flters和proxyFilters, filter都是内置的,想通过proxyFilters来定制的话,就不要配置filters;如果同时配置也会报错,会让人产出配置没有生效的错觉。
同时配置的的情况如图所示:
错误示例
我最开始这样配置,执行批量删除sql一样报错,排查了好半天才发现不能同时配置,因此放个错误示例,避免同志们踩坑!!!

2、druid配置类优先级大于项目的配置文件。
比如在使用druid控制台访问时,配置文件配置了登录账号和密码,druid配置类也配置了账号和密码,并且账号和密码不一样!使用配置文件的账号密码登录会一直报错,使用druid配置类配置的账号密码登录可正常登录跳转!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值