当前位置: 代码迷 >> 综合 >> spring cloud+mybatis+阿里Druid:如何开启配置multiStatementAllow支持一次执行多条sql
  详细解决方案

spring cloud+mybatis+阿里Druid:如何开启配置multiStatementAllow支持一次执行多条sql

热度:79   发布时间:2024-01-31 21:10:49.0

 

关于如何开启multiStatementAllow,一次执行多条sql,这里结合项目,来说明一下。

 

首先搞清楚,multiStatementAllow配置在哪,其实就是阿里Druid框架中WallConfig.class中的一个属性。源码如下:

 

package com.alibaba.druid.wall;import com.alibaba.druid.util.Utils;
import com.alibaba.druid.wall.spi.WallVisitorUtils;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;public class WallConfig implements WallConfigMBean {private boolean noneBaseStatementAllow = false;private boolean callAllow = true;private boolean selelctAllow = true;private boolean selectIntoAllow = true;private boolean selectIntoOutfileAllow = false;private boolean selectWhereAlwayTrueCheck = true;private boolean selectHavingAlwayTrueCheck = true;private boolean selectUnionCheck = true;private boolean selectMinusCheck = true;private boolean selectExceptCheck = true;private boolean selectIntersectCheck = true;private boolean createTableAllow = true;private boolean dropTableAllow = true;private boolean alterTableAllow = true;private boolean renameTableAllow = true;private boolean hintAllow = true;private boolean lockTableAllow = true;private boolean startTransactionAllow = true;private boolean conditionAndAlwayTrueAllow = false;private boolean conditionAndAlwayFalseAllow = false;private boolean conditionDoubleConstAllow = false;private boolean conditionLikeTrueAllow = true;private boolean selectAllColumnAllow = true;private boolean deleteAllow = true;private boolean deleteWhereAlwayTrueCheck = true;private boolean deleteWhereNoneCheck = false;private boolean updateAllow = true;private boolean updateWhereAlayTrueCheck = true;private boolean updateWhereNoneCheck = false;private boolean insertAllow = true;private boolean mergeAllow = true;private boolean minusAllow = true;private boolean intersectAllow = true;private boolean replaceAllow = true;private boolean setAllow = true;private boolean commitAllow = true;private boolean rollbackAllow = true;private boolean useAllow = true;private boolean multiStatementAllow = false;private boolean truncateAllow = true;private boolean commentAllow = false;private boolean strictSyntaxCheck = true;private boolean constArithmeticAllow = true;private boolean limitZeroAllow = false;private boolean describeAllow = true;private boolean showAllow = true;private boolean schemaCheck = true;private boolean tableCheck = true;private boolean functionCheck = true;private boolean objectCheck = true;private boolean variantCheck = true;private boolean mustParameterized = false;private boolean doPrivilegedAllow = false;protected final Set<String> denyFunctions = new ConcurrentSkipListSet();protected final Set<String> denyTables = new ConcurrentSkipListSet();protected final Set<String> denySchemas = new ConcurrentSkipListSet();protected final Set<String> denyVariants = new ConcurrentSkipListSet();protected final Set<String> denyObjects = new ConcurrentSkipListSet();protected final Set<String> permitFunctions = new ConcurrentSkipListSet();protected final Set<String> permitTables = new ConcurrentSkipListSet();protected final Set<String> permitSchemas = new ConcurrentSkipListSet();protected final Set<String> permitVariants = new ConcurrentSkipListSet();protected final Set<String> readOnlyTables = new ConcurrentSkipListSet();private String dir;private boolean inited;private String tenantTablePattern;private String tenantColumn;private WallConfig.TenantCallBack tenantCallBack;private boolean wrapAllow = true;private boolean metadataAllow = true;private boolean conditionOpXorAllow = false;private boolean conditionOpBitwseAllow = true;private boolean caseConditionConstAllow = false;private boolean completeInsertValuesCheck = false;private int insertValuesCheckSize = 3;... 省略
}
multiStatementAllow默认值为false,也就是说默认不开启一次执行多条sql语句的。

 

如何支持呢?本质就是把multiStatementAllow的值置为false,但是考虑到不同项目,数据源的配置是不同的,所以具体的实现

方案也是不同的。但是核心思想是不变的,我们需要拦截数据源,然后把我们的修改注入到Datasource。

 

    @Bean(name = "wallFilter")@DependsOn("wallConfig")public WallFilter wallFilter(WallConfig wallConfig) {WallFilter wallFilter = new WallFilter();wallFilter.setConfig(wallConfig);return wallFilter;}@Bean(name = "wallConfig")public WallConfig wallConfig() {WallConfig wallConfig = new WallConfig();wallConfig.setMultiStatementAllow(Boolean.TRUE);return wallConfig;}

 

如何把这个filter注入到datasource呢,如果我们可以直接获取到datasource的话,那么,直接按照网上的方式,就可以了。如下

List<Filter> filters = new ArrayList<>();
filters.add(wallFilter);
datasource.setProxyFilters(filters);

 

但是有些项目,数据源是进行了统一的管理的,也就是我们不能直接获取到datasource,只能通过配置来注入这个filter,

怎么办呢?思路是:找到filter配置,然后把我们自定义的filter这个bean:wallFilter配置上去即可。

 

xx:xxxx:server:enablecache: truedatasource:driver : com.mysql.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/databasename?serverTimezone=GMT%2b8&useSSL=false&Unicode=true&characterEncoding=utf8&autoReconnectForPools=true&allowMultiQueries=trueuser: rootpassword: 123456789mapperLocations: classpath:mybatis/*.xmltimeBetweenEvictionRunsMillis: 60000filters: wallFilter

 

这样配置以后,我们就可以执行下面这种多条sql了。

 

    <update id="batchUpdateTest"><foreach collection="pojos" item="pojo" index="index" open="" close="" separator=";">UPDATE table_nameSET `name` = #{pojo.name},`update_time` = #{pojo.updateTime}WHERE `id` = #{pojo.id} and  `code` = #{pojo.code}</foreach></update>

 

  相关解决方案