详细代码参见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
网友评论