Springboot+Druid完美支持批量数据更新

详细代码参见https://github.com/biticcf/ocean-sea-platform.git或者https://gitee.com/biticcf/ocean-sea-platform.git

默认情况下,启用wall拦截器的druid是不支持批量数据更新的,原因在于wall拦截器默认是关闭批量更新功能的,因此我们只需要开启此功能,就能让druid支持批量更新了。
大家可以看下druid的源代码,它有两种方式支持filter的配置:
1,filters:
官方说明如下:


filters官方说明

该配置仅支持druid-filter.properties文件中定义的若干种filters,并且也无法定制其各项属性值,他的配置方式是:

druid: 
  filters: stat,mergeStat,slf4j,wall

2,proxyFilters:
官方说明如下:


proxyFilters官方说明

该配置目前不能通过properties或者yml的方式使用,但可以通过代码的方式动态注入。
网上讲的最多的也是这种方式,但是这种方式入侵性很强,缺乏代码优雅和通用性,因此这里不再赘述。
3,其他配置方式:大多配置比较复杂,这里也不再赘述。

4,我们要讲的是一种全新的配置方式,该方式基于配置文件,不具备代码入侵性,步骤如下:
4.1,springboot的核心是通过配置文件实现bean定义,我们遵循这一原则,实现一种能够直接注入bean的,定义我们自己的DataSource,我这里叫做extFilters:

package com.github.biticcf.mountain.core.common.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;

public class MountainDruidDataSource extends DruidDataSource implements ApplicationContextAware {
    private static final long serialVersionUID = 5392430401971221841L;

    private ApplicationContext applicationContext;
    
    private List<Filter> extFilters;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    /**
     * +根据bean的name设置fliter
     * @param filters bean的name
     */
    public void setExtFilters(List<String> filters) {
        if (filters == null || filters.isEmpty()) {
            return;
        }
        
        this.extFilters = new ArrayList<>();
        // 加载新的filters
        for (String beanName : filters) {
            Filter filter = null;
            try {
                filter = applicationContext.getBean(beanName, Filter.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (filter != null) {
                extFilters.add(filter);
            }
        }
        if (!extFilters.isEmpty()) {
            setProxyFilters(extFilters);
        }
    }
    
    /**
     * + 获取所有的extFilters
     * @return extFilters
     */
    public List<Filter> getExtFilters (){
        return this.extFilters;
    }
}

4.2,更改数据连接池配置的类型

spring: 
  datasource: 
    # 使用自定义druid数据库连接池
    type: com.github.biticcf.mountain.core.common.service.MountainDruidDataSource

数据源的加载方式如下:

    @Value("${spring.datasource.type}")
    private Class<? extends DataSource> datasourceType;
        ....
    @Bean(name = "dataSource", destroyMethod = "close")
    @Primary
    @ConfigurationProperties(prefix = "datasource.master")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(datasourceType).build();
    }

这种数据源加载方式是完全通用的,不会根据连接池的改变而改变。
4.3,定义我们的WallFilter

    @Bean(name = "wallFilter")
    @ConfigurationProperties(prefix = "druid.filters.wall")
    public WallFilter wallFilter() {
        return new WallFilter();
    }

4.4,配置我们自己需要的属性

datasource:
  master: 
    filters: stat,mergeStat,slf4j
    extFilters: 
     - wallFilter

druid: 
  filters: 
    wall: 
      logViolation: false
      throwException: true
      config: 
        multiStatementAllow: true #true开启批量更新
        noneBaseStatementAllow: true

这里要注意,数据库连接的url需要配置allowMultiQueries=true参数。

OK,这样配置后,你的代码就可以支持批量更新操作啦~
完整代码请参见

https://github.com/biticcf/ocean-sea-platform.git

或者

https://gitee.com/biticcf/ocean-sea-platform.git
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容