druid配置spring.datasource.filters导致mybatis批量更新报错sql injection violation, multi-statement not allow

这个错是druid配置开启了数据监控导致的。
修改前:
在这里插入图片描述
修改filters:
在这里插入图片描述

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;
 
@Configuration
public class DruidConfig {
 
    private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);
 
    private static final String DB_PREFIX = "spring.datasource";
 
    @Bean
    public ServletRegistrationBean druidServlet() {
        logger.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow", "*");
        // IP黑名单(共同存在时,deny优先于allow)
        servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "admin123*");
        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }
 
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
    //  --------------------------- 配置相关的监控过滤器----  
    @Autowired
    WallFilter wallFilter;
    
    @Bean(name = "wallConfig")
    WallConfig wallFilterConfig() {
        WallConfig wc = new WallConfig();
        wc.setMultiStatementAllow(true);
        return wc;
    }
    
    @Bean(name = "wallFilter")
    @DependsOn("wallConfig")
    WallFilter wallFilter(WallConfig wallConfig) {
        WallFilter wfilter = new WallFilter();
        wfilter.setConfig(wallConfig);
        return wfilter;
    }
 //  --------------------------- 配置相关的监控过滤器----结束-------------------
    //解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
    @ConfigurationProperties(prefix = DB_PREFIX)
    class IDataSourceProperties {
        private String url;
        private String username;
        private String password;
        private String driverClassName;
        private int initialSize;
        private int minIdle;
        private int maxActive;
        private int maxWait;
        private int timeBetweenEvictionRunsMillis;
        private int minEvictableIdleTimeMillis;
        private String validationQuery;
        private boolean testWhileIdle;
        private boolean testOnBorrow;
        private boolean testOnReturn;
        private boolean poolPreparedStatements;
        private int maxPoolPreparedStatementPerConnectionSize;
        private String filters;
        private String connectionProperties;
 
        @Bean     //声明其为Bean实例
        @Primary  //在同样的DataSource中,首先使用被标注的DataSource
        public DataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);
 
            //configuration
            datasource.setInitialSize(initialSize);
            datasource.setMinIdle(minIdle);
            datasource.setMaxActive(maxActive);
            datasource.setMaxWait(maxWait);
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(testWhileIdle);
            datasource.setTestOnBorrow(testOnBorrow);
            datasource.setTestOnReturn(testOnReturn);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
            try {
            	//这里添加代理过滤器
            	List<Filter> proxyFilters = new ArrayList<>();
                proxyFilters.add(wallFilter);
                datasource.setProxyFilters(proxyFilters);
                datasource.setFilters(filters);
            } catch (SQLException e) {
                System.err.println("druid configuration initialization filter: " + e);
            }
            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }
 
        public String getUrl() {
            return url;
        }
 
        public void setUrl(String url) {
            this.url = url;
        }
 
        public String getUsername() {
            return username;
        }
 
        public void setUsername(String username) {
            this.username = username;
        }
 
        public String getPassword() {
            return password;
        }
 
        public void setPassword(String password) {
            this.password = password;
        }
 
        public String getDriverClassName() {
            return driverClassName;
        }
 
        public void setDriverClassName(String driverClassName) {
            this.driverClassName = driverClassName;
        }
 
        public int getInitialSize() {
            return initialSize;
        }
 
        public void setInitialSize(int initialSize) {
            this.initialSize = initialSize;
        }
 
        public int getMinIdle() {
            return minIdle;
        }
 
        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }
 
        public int getMaxActive() {
            return maxActive;
        }
 
        public void setMaxActive(int maxActive) {
            this.maxActive = maxActive;
        }
 
        public int getMaxWait() {
            return maxWait;
        }
 
        public void setMaxWait(int maxWait) {
            this.maxWait = maxWait;
        }
 
        public int getTimeBetweenEvictionRunsMillis() {
            return timeBetweenEvictionRunsMillis;
        }
 
        public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
            this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
        }
 
        public int getMinEvictableIdleTimeMillis() {
            return minEvictableIdleTimeMillis;
        }
 
        public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
            this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
        }
 
        public String getValidationQuery() {
            return validationQuery;
        }
 
        public void setValidationQuery(String validationQuery) {
            this.validationQuery = validationQuery;
        }
 
        public boolean isTestWhileIdle() {
            return testWhileIdle;
        }
 
        public void setTestWhileIdle(boolean testWhileIdle) {
            this.testWhileIdle = testWhileIdle;
        }
 
        public boolean isTestOnBorrow() {
            return testOnBorrow;
        }
 
        public void setTestOnBorrow(boolean testOnBorrow) {
            this.testOnBorrow = testOnBorrow;
        }
 
        public boolean isTestOnReturn() {
            return testOnReturn;
        }
 
        public void setTestOnReturn(boolean testOnReturn) {
            this.testOnReturn = testOnReturn;
        }
 
        public boolean isPoolPreparedStatements() {
            return poolPreparedStatements;
        }
 
        public void setPoolPreparedStatements(boolean poolPreparedStatements) {
            this.poolPreparedStatements = poolPreparedStatements;
        }
 
        public int getMaxPoolPreparedStatementPerConnectionSize() {
            return maxPoolPreparedStatementPerConnectionSize;
        }
 
        public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
            this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
        }
 
        public String getFilters() {
            return filters;
        }
 
        public void setFilters(String filters) {
            this.filters = filters;
        }
 
        public String getConnectionProperties() {
            return connectionProperties;
        }
 
        public void setConnectionProperties(String connectionProperties) {
            this.connectionProperties = connectionProperties;
        }
    }
 
}
Spring Boot项目中,可以使用编程式控制事务的方式来保证数据库操作的一致性和完整性。具体实现方式如下: 1.Spring Boot项目中引入Spring事务的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> ``` 2.配置文件中配置数据源和事务管理器: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 配置事务管理器 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=20 spring.datasource.druid.max-wait=60000 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.validation-query=SELECT 1 FROM DUAL spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false # 配置事务管理器 spring.datasource.druid.filters=stat,wall spring.datasource.druid.use-global-data-source-stat=true # 配置事务管理器 spring.datasource.druid.filter.stat.log-slow-sql=true spring.datasource.druid.filter.stat.slow-sql-millis=2000 # 配置事务管理器 spring.datasource.druid.filter.wall.log-violation=true spring.datasource.druid.filter.wall.throw-error=false spring.datasource.druid.filter.wall.update-allow=true spring.datasource.druid.filter.wall.delete-allow=true spring.datasource.druid.filter.wall.insert-allow=true spring.datasource.druid.filter.wall.select-allow=true spring.datasource.druid.filter.wall.multi-statement-allow=true # 配置事务管理器 spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 配置事务管理器 spring.datasource.druid.connection-init-sqls=SET NAMES utf8mb4 COLLATE utf8mb4_general_ci # 配置事务管理器 spring.datasource.druid.use-global-data-source-stat=true # 配置事务管理器 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 # 配置事务管理器 spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 # 配置事务管理器 mybatis.configuration.map-underscore-to-camel-case=true mybatis.mapper-locations=classpath*:mapper/*.xml # 配置事务管理器 spring.datasource.druid.stat-view-servlet.allow=true spring.datasource.druid.web-stat-filter.enabled=true spring.datasource.druid.stat-view-servlet.url-pattern=/druid/* spring.datasource.druid.stat-view-servlet.login-username=admin spring.datasource.druid.stat-view-servlet.login-password=admin ``` 3. 在需要实现事务的方法上添加`@Transactional`注解: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override @Transactional(rollbackFor = Exception.class) public void save(User user) { userMapper.save(user); //抛出异常 throw new RuntimeException("test transactional"); } } ``` 4. 在需要调用事务的地方调用上述方法即可: ```java @RestController public class UserController { @Autowired private UserService userService; @PostMapping("/user") public void save(@RequestBody User user) { userService.save(user); } } ``` 以上就是在Spring Boot项目中使用编程式控制事务的步骤和示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值