diff --git a/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java b/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java index 319f2ffd..ce0c6225 100644 --- a/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java +++ b/backend/src/main/java/com/yfd/platform/common/MicroservicDynamicSQLMapper.java @@ -4,6 +4,8 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.datasource.DataSourceKeys; +import com.yfd.platform.datasource.TargetDataSource; import org.apache.ibatis.annotations.Mapper; import java.util.Collections; @@ -30,6 +32,11 @@ public interface MicroservicDynamicSQLMapper { Map getOneBySql(@Param("sql") String sql, @Param("map") Map map); + @Select({""}) + @TargetDataSource(DataSourceKeys.ORACLE_MASTER) + Map getOneOracleBySql(@Param("sql") String sql, @Param("map") Map map); + + default R getOneBySqlWithResultType(String sql, Map map, Class resultType) { diff --git a/backend/src/main/java/com/yfd/platform/config/DynamicPaginationInterceptor.java b/backend/src/main/java/com/yfd/platform/config/DynamicPaginationInterceptor.java new file mode 100644 index 00000000..79598636 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/config/DynamicPaginationInterceptor.java @@ -0,0 +1,41 @@ +package com.yfd.platform.config; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.yfd.platform.datasource.DynamicDataSource; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; + +import java.sql.SQLException; + +/** + * 动态分页拦截器,根据当前数据源自动切换 Oracle/DM 分页方言 + */ +public class DynamicPaginationInterceptor extends PaginationInnerInterceptor { + + public DynamicPaginationInterceptor() { + super(DbType.DM); + } + + @Override + public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, + RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { + this.setDbType(resolveDbType()); + super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql); + } + + /** + * 根据当前线程绑定的数据源 key 解析数据库类型: + * oracle-* → ORACLE,其他(dm-*、null)→ DM + */ + private DbType resolveDbType() { + String dsKey = DynamicDataSource.getDataSource(); + if (dsKey != null && dsKey.startsWith("oracle")) { + return DbType.ORACLE; + } + return DbType.DM; + } +} diff --git a/backend/src/main/java/com/yfd/platform/config/MybitsPlusConfig.java b/backend/src/main/java/com/yfd/platform/config/MybitsPlusConfig.java index eff73ed2..171503b6 100644 --- a/backend/src/main/java/com/yfd/platform/config/MybitsPlusConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/MybitsPlusConfig.java @@ -1,37 +1,19 @@ package com.yfd.platform.config; -import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; -import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -/****************************** - * 用途说明: - * 作者姓名: pcj - * 创建时间: 2022/10/24 10:50 - ******************************/ +/** + * MyBatis-Plus 配置,使用动态分页拦截器支持 Oracle/达梦 自动切换 + */ @Configuration public class MybitsPlusConfig { -// @Bean -// public MybatisPlusInterceptor mybatisPlusInterceptor() { -// MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); -// mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); -// return mybatisPlusInterceptor; -// } - - /** - * 分页插件配置(Oracle 兼容) - */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); - // 添加分页拦截器,指定数据库类型为 Oracle -// interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE)); - // 添加分页拦截器,指定数据库类型为 Oracle - interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.DM)); + interceptor.addInnerInterceptor(new DynamicPaginationInterceptor()); return interceptor; } - } diff --git a/backend/src/main/java/com/yfd/platform/datasource/DataSourceAspect.java b/backend/src/main/java/com/yfd/platform/datasource/DataSourceAspect.java index f20c0f87..33b7fb28 100644 --- a/backend/src/main/java/com/yfd/platform/datasource/DataSourceAspect.java +++ b/backend/src/main/java/com/yfd/platform/datasource/DataSourceAspect.java @@ -1,55 +1,41 @@ package com.yfd.platform.datasource; -import cn.hutool.core.util.StrUtil; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; -import java.lang.reflect.Method; - -/****************************** - * 用途说明: - * 作者姓名: wxy - * 创建时间: 2022/9/23 17:50 - ******************************/ +/** + * 数据源切换切面,处理 @TargetDataSource 注解 + */ @Aspect @Component public class DataSourceAspect { - @Pointcut("@annotation(com.yfd.platform.datasource.DataSource)") + @Pointcut("@annotation(com.yfd.platform.datasource.TargetDataSource)") public void dataSourcePointCut() { - } - private String DataBaseName; - @Around("dataSourcePointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { MethodSignature signature = (MethodSignature) point.getSignature(); - Method method = signature.getMethod(); - if (StrUtil.isNotBlank(DataBaseName)){ - DynamicDataSource.setDataSource(DataBaseName); - }else { - DynamicDataSource.setDataSource("master"); + TargetDataSource annotation = AnnotationUtils.findAnnotation(signature.getMethod(), TargetDataSource.class); + if (annotation == null) { + // 类级别注解 + annotation = AnnotationUtils.findAnnotation(point.getTarget().getClass(), TargetDataSource.class); } + String dsKey = (annotation != null && !annotation.value().isEmpty()) + ? annotation.value() + : DataSourceKeys.DEFAULT; + DynamicDataSource.setDataSource(dsKey); try { return point.proceed(); } finally { DynamicDataSource.clearDataSource(); } } - - public String getDataBase(Integer type){ - if (type == 1){ - DataBaseName="master"; - }else { - DataBaseName="slave"; - } - return DataBaseName; - } - } diff --git a/backend/src/main/java/com/yfd/platform/datasource/DataSourceKeys.java b/backend/src/main/java/com/yfd/platform/datasource/DataSourceKeys.java new file mode 100644 index 00000000..19a8459a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/datasource/DataSourceKeys.java @@ -0,0 +1,22 @@ +package com.yfd.platform.datasource; + +/** + * 数据源 key 常量 + */ +public interface DataSourceKeys { + + /** 达梦主库 */ + String DM_MASTER = "dm-master"; + + /** 达梦从库 */ + String DM_SLAVE = "dm-slave"; + + /** Oracle 主库 */ + String ORACLE_MASTER = "oracle-master"; + + /** Oracle 从库 */ + String ORACLE_SLAVE = "oracle-slave"; + + /** 默认数据源 */ + String DEFAULT = DM_MASTER; +} diff --git a/backend/src/main/java/com/yfd/platform/datasource/DynamicDataSourceConfig.java b/backend/src/main/java/com/yfd/platform/datasource/DynamicDataSourceConfig.java index f5594437..d9e984ae 100644 --- a/backend/src/main/java/com/yfd/platform/datasource/DynamicDataSourceConfig.java +++ b/backend/src/main/java/com/yfd/platform/datasource/DynamicDataSourceConfig.java @@ -1,28 +1,28 @@ package com.yfd.platform.datasource; +import com.alibaba.druid.pool.DruidDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; -import com.alibaba.druid.pool.DruidDataSource; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; -/****************************** - * 用途说明: - * 作者姓名: wxy - * 创建时间: 2022/9/23 17:45 - ******************************/ +/** + * 动态数据源配置,支持 达梦(DM) 和 Oracle 两种数据库,每种各有主从(master/slave) + * + * @author yfd + */ @Configuration -@Component public class DynamicDataSourceConfig { + // ==================== 达梦(DM) 数据源 ==================== + @Bean - @ConfigurationProperties("spring.datasource.druid.master") - public DataSource wglMasterDataSource(){ + @ConfigurationProperties("spring.datasource.druid.dm-master") + public DataSource dmMasterDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setBreakAfterAcquireFailure(true); dataSource.setConnectionErrorRetryAttempts(0); @@ -30,22 +30,48 @@ public class DynamicDataSourceConfig { } @Bean - @ConfigurationProperties("spring.datasource.druid.slave") - public DataSource wglSlaveDataSource(){ + @ConfigurationProperties("spring.datasource.druid.dm-slave") + public DataSource dmSlaveDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setBreakAfterAcquireFailure(true); dataSource.setConnectionErrorRetryAttempts(0); return dataSource; } + // ==================== Oracle 数据源 ==================== + + @Bean + @ConfigurationProperties("spring.datasource.druid.oracle-master") + public DataSource oracleMasterDataSource() { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setBreakAfterAcquireFailure(true); + dataSource.setConnectionErrorRetryAttempts(0); + return dataSource; + } + + @Bean + @ConfigurationProperties("spring.datasource.druid.oracle-slave") + public DataSource oracleSlaveDataSource() { + DruidDataSource dataSource = new DruidDataSource(); + dataSource.setBreakAfterAcquireFailure(true); + dataSource.setConnectionErrorRetryAttempts(0); + return dataSource; + } + + // ==================== 路由数据源 ==================== + @Bean @Primary - public DynamicDataSource dataSource(DataSource wglMasterDataSource, DataSource wglSlaveDataSource) { + public DynamicDataSource dataSource(DataSource dmMasterDataSource, + DataSource dmSlaveDataSource, + DataSource oracleMasterDataSource, + DataSource oracleSlaveDataSource) { Map targetDataSources = new HashMap<>(); - targetDataSources.put("master",wglMasterDataSource); - targetDataSources.put("slave",wglSlaveDataSource); - return new DynamicDataSource(wglMasterDataSource, targetDataSources); + targetDataSources.put(DataSourceKeys.DM_MASTER, dmMasterDataSource); + targetDataSources.put(DataSourceKeys.DM_SLAVE, dmSlaveDataSource); + targetDataSources.put(DataSourceKeys.ORACLE_MASTER, oracleMasterDataSource); + targetDataSources.put(DataSourceKeys.ORACLE_SLAVE, oracleSlaveDataSource); + // 默认使用达梦主库 + return new DynamicDataSource(dmMasterDataSource, targetDataSources); } - - } diff --git a/backend/src/main/java/com/yfd/platform/datasource/TargetDataSource.java b/backend/src/main/java/com/yfd/platform/datasource/TargetDataSource.java new file mode 100644 index 00000000..b208ff44 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/datasource/TargetDataSource.java @@ -0,0 +1,23 @@ +package com.yfd.platform.datasource; + +import java.lang.annotation.*; + +/** + * 动态数据源注解,用于方法级别切换数据源 + *

+ * 支持的取值: + *

    + *
  • "dm-master" / "dm-slave" — 达梦数据库
  • + *
  • "oracle-master" / "oracle-slave" — Oracle 数据库
  • + *
+ * 默认值为 "dm-master" + * + * @author yfd + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface TargetDataSource { + + String value() default DataSourceKeys.DM_MASTER; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java index aecb081b..18f77b3a 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_sys/mapLayer/service/impl/MapLegendServiceImpl.java @@ -33,10 +33,10 @@ public class MapLegendServiceImpl extends ServiceImpl + * 支持的 dataSourceKey: + *
    + *
  • "dm-master" / "dm-slave" — 达梦数据库
  • + *
  • "oracle-master" / "oracle-slave" — Oracle 数据库
  • + *
+ * 注意:此方法仅对当前请求线程生效,且必须在被 @TargetDataSource 注解的方法中使用才会真正路由。 + * 建议使用 @TargetDataSource 注解方式切换数据源。 */ @GetMapping("/changeDataSource") @Operation(summary = "切换数据库") - public ResponseResult changeDataSource(Integer type) { + @Deprecated + public ResponseResult changeDataSource(@RequestParam(required = false) Integer type) { if (type == null) { return ResponseResult.error("参数为空"); } - String dataBase = dataSourceAspect.getDataBase(type); - String mess = "已切换为" + dataBase + "数据库"; - return ResponseResult.success(mess); + String dataSourceKey = (type == 1) ? DataSourceKeys.DM_MASTER : DataSourceKeys.DM_SLAVE; + DynamicDataSource.setDataSource(dataSourceKey); + return ResponseResult.success("已切换为" + dataSourceKey + "数据源"); } - } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java index 77506150..b860f0bd 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserDetailsServiceImpl.java @@ -4,6 +4,8 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.yfd.platform.datasource.DataSource; +import com.yfd.platform.datasource.DataSourceKeys; +import com.yfd.platform.datasource.TargetDataSource; import com.yfd.platform.system.domain.LoginUser; import com.yfd.platform.system.domain.SysUser; import com.yfd.platform.system.mapper.SysMenuMapper; @@ -38,7 +40,7 @@ public class UserDetailsServiceImpl implements UserDetailsService { private SysMenuMapper sysMenuMapper; @Override - @DataSource(name = "master") + @TargetDataSource() public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 获取当前请求 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); diff --git a/backend/src/main/resources/application-dev.yml b/backend/src/main/resources/application-dev.yml index ccbcb104..31f5159d 100644 --- a/backend/src/main/resources/application-dev.yml +++ b/backend/src/main/resources/application-dev.yml @@ -8,16 +8,30 @@ spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: - master: + # ==================== 达梦(DM) 数据源 ==================== + dm-master: driverClassName: dm.jdbc.driver.DmDriver - url: "${DB_MASTER_URL:jdbc:dm://localhost:5236/WPPDB}" - username: "${DB_MASTER_USERNAME:WPPDB}" - password: "${DB_MASTER_PASSWORD:}" - slave: + url: "${DB_DM_MASTER_URL:jdbc:dm://localhost:5236/WPPDB}" + username: "${DB_DM_MASTER_USERNAME:WPPDB}" + password: "${DB_DM_MASTER_PASSWORD:}" + dm-slave: driverClassName: dm.jdbc.driver.DmDriver - url: "${DB_SLAVE_URL:jdbc:dm://localhost:5236/WPPDB}" - username: "${DB_SLAVE_USERNAME:WPPDB}" - password: "${DB_SLAVE_PASSWORD:}" + url: "${DB_DM_SLAVE_URL:jdbc:dm://localhost:5236/WPPDB}" + username: "${DB_DM_SLAVE_USERNAME:WPPDB}" + password: "${DB_DM_SLAVE_PASSWORD:}" + # ==================== Oracle 数据源 ==================== + oracle-master: + driverClassName: oracle.jdbc.OracleDriver + url: "${DB_ORACLE_MASTER_URL:jdbc:oracle:thin:@localhost:1521/ORCL}" + username: "${DB_ORACLE_MASTER_USERNAME:}" + password: "${DB_ORACLE_MASTER_PASSWORD:}" + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 + oracle-slave: + driverClassName: oracle.jdbc.OracleDriver + url: "${DB_ORACLE_SLAVE_URL:jdbc:oracle:thin:@localhost:1521/ORCL}" + username: "${DB_ORACLE_SLAVE_USERNAME:}" + password: "${DB_ORACLE_SLAVE_PASSWORD:}" + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 mvc: pathmatch: diff --git a/backend/src/main/resources/application-prod.yml b/backend/src/main/resources/application-prod.yml index cc37ba65..f7005940 100644 --- a/backend/src/main/resources/application-prod.yml +++ b/backend/src/main/resources/application-prod.yml @@ -10,13 +10,12 @@ spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: - master: -# driverClassName: oracle.jdbc.OracleDriver -# url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}" + # ==================== 达梦(DM) 数据源 ==================== + dm-master: driverClassName: dm.jdbc.driver.DmDriver - url: "${DB_MASTER_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}" - username: "${DB_MASTER_USERNAME:QGC_REFA}" - password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}" + url: "${DB_DM_MASTER_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}" + username: "${DB_DM_MASTER_USERNAME:QGC_REFA}" + password: "${DB_DM_MASTER_PASSWORD:Y4M4K1oCkL8U}" initial-size: 5 min-idle: 5 max-active: 20 @@ -41,15 +40,11 @@ spring: pool-prepared-statements: true max-open-prepared-statements: 100 max-pool-prepared-statement-per-connection-size: 100 - connection-properties: connectTimeout=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 -# connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 - slave: + dm-slave: driverClassName: dm.jdbc.driver.DmDriver - url: "${DB_MASTER_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}" -# driverClassName: oracle.jdbc.OracleDriver -# url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}" - username: "${DB_SLAVE_USERNAME:QGC_REFA}" - password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}" + url: "${DB_DM_SLAVE_URL:jdbc:dm://172.16.21.143:5236/QGC_REFA}" + username: "${DB_DM_SLAVE_USERNAME:QGC_REFA}" + password: "${DB_DM_SLAVE_PASSWORD:Y4M4K1oCkL8U}" initial-size: 5 min-idle: 5 max-active: 20 @@ -74,8 +69,67 @@ spring: pool-prepared-statements: true max-open-prepared-statements: 100 max-pool-prepared-statement-per-connection-size: 100 - connection-properties: connectTimeout=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 -# connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 + # ==================== Oracle 数据源 ==================== + oracle-master: + driverClassName: oracle.jdbc.OracleDriver + url: "${DB_ORACLE_MASTER_URL:jdbc:oracle:thin:@172.16.31.172:1521/SDLYZ}" + username: "${DB_ORACLE_MASTER_USERNAME:SDLY_QX}" + password: "${DB_ORACLE_MASTER_PASSWORD:jNHnqv3hH7}" + initial-size: 5 + min-idle: 5 + max-active: 20 + max-wait: 30000 + async-init: true + keep-alive-between-time-millis: 120000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 180000 + max-evictable-idle-time-millis: 300000 + phy-timeout-millis: 25200000 + validation-query: SELECT 1 FROM DUAL + validation-query-timeout: 3 + test-while-idle: true + test-on-borrow: false + test-on-return: false + keep-alive: true + remove-abandoned: true + remove-abandoned-timeout: 1800 + log-abandoned: true + break-after-acquire-failure: true + time-between-connect-error-millis: 30000 + pool-prepared-statements: true + max-open-prepared-statements: 100 + max-pool-prepared-statement-per-connection-size: 100 + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 + oracle-slave: + driverClassName: oracle.jdbc.OracleDriver + url: "${DB_ORACLE_SLAVE_URL:jdbc:oracle:thin:@172.16.31.172:1521/SDLYZ}" + username: "${DB_ORACLE_SLAVE_USERNAME:SDLY_QX}" + password: "${DB_ORACLE_SLAVE_PASSWORD:jNHnqv3hH7}" + initial-size: 5 + min-idle: 5 + max-active: 20 + max-wait: 30000 + async-init: true + keep-alive-between-time-millis: 120000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 180000 + max-evictable-idle-time-millis: 300000 + phy-timeout-millis: 25200000 + validation-query: SELECT 1 FROM DUAL + validation-query-timeout: 3 + test-while-idle: true + test-on-borrow: false + test-on-return: false + keep-alive: true + remove-abandoned: true + remove-abandoned-timeout: 1800 + log-abandoned: true + break-after-acquire-failure: true + time-between-connect-error-millis: 30000 + pool-prepared-statements: true + max-open-prepared-statements: 100 + max-pool-prepared-statement-per-connection-size: 100 + connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000 filter: stat: enabled: true