mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-14 22:29:00 +08:00
refactor(common-datasource): 重构动态数据源,同支持 YAML + JDBC ,兼容Druid 标准配置
This commit is contained in:
1 parent
4cb2e1ceae
commit
f97295cef1
3 files changed
+175
-87
No files matched your search
+65
-49
@@ -53,57 +53,73 @@ import java.util.List;
|
|||||||
@EnableConfigurationProperties(DruidDataSourceProperties.class)
|
@EnableConfigurationProperties(DruidDataSourceProperties.class)
|
||||||
public class DynamicDataSourceAutoConfiguration {
|
public class DynamicDataSourceAutoConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取动态数据源提供者
|
* 获取动态数据源提供者
|
||||||
* @param defaultDataSourceCreator 默认数据源创建器
|
*
|
||||||
* @param stringEncryptor 字符串加密器
|
* @param defaultDataSourceCreator 默认数据源创建器
|
||||||
* @param properties 数据源属性
|
* @param stringEncryptor 字符串加密器
|
||||||
* @return 动态数据源提供者
|
* @param properties 数据源属性
|
||||||
*/
|
* @return 动态数据源提供者
|
||||||
@Bean
|
*/
|
||||||
public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator,
|
@Bean
|
||||||
StringEncryptor stringEncryptor, DruidDataSourceProperties properties) {
|
public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator,
|
||||||
return new JdbcDynamicDataSourceProvider(defaultDataSourceCreator, stringEncryptor, properties);
|
StringEncryptor stringEncryptor, DruidDataSourceProperties properties) {
|
||||||
}
|
return new JdbcDynamicDataSourceProvider(defaultDataSourceCreator, stringEncryptor, properties);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取默认数据源创建器
|
* 主数据源提供程序
|
||||||
* @param druidDataSourceCreator Druid数据源创建器
|
*
|
||||||
* @return 默认数据源创建器
|
* @param defaultDataSourceCreator 默认数据源创建者
|
||||||
*/
|
* @param properties 性能
|
||||||
@Bean
|
* @return {@link DynamicDataSourceProvider }
|
||||||
public DefaultDataSourceCreator defaultDataSourceCreator(DruidDataSourceCreator druidDataSourceCreator) {
|
*/
|
||||||
DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator();
|
@Bean
|
||||||
List<DataSourceCreator> creators = new ArrayList<>();
|
public DynamicDataSourceProvider masterDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator, DruidDataSourceProperties properties) {
|
||||||
creators.add(druidDataSourceCreator);
|
return new MasterDataSourceProvider(defaultDataSourceCreator, properties);
|
||||||
defaultDataSourceCreator.setCreators(creators);
|
}
|
||||||
return defaultDataSourceCreator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取数据源处理器
|
* 获取默认数据源创建器
|
||||||
* @return 数据源处理器
|
*
|
||||||
*/
|
* @param druidDataSourceCreator Druid数据源创建器
|
||||||
@Bean
|
* @return 默认数据源创建器
|
||||||
public DsProcessor dsProcessor(BeanFactory beanFactory) {
|
*/
|
||||||
DsProcessor lastParamDsProcessor = new LastParamDsProcessor();
|
@Bean
|
||||||
DsProcessor headerProcessor = new DsHeaderProcessor();
|
public DefaultDataSourceCreator defaultDataSourceCreator(DruidDataSourceCreator druidDataSourceCreator) {
|
||||||
DsProcessor sessionProcessor = new DsSessionProcessor();
|
DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator();
|
||||||
DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
|
List<DataSourceCreator> creators = new ArrayList<>();
|
||||||
spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
|
creators.add(druidDataSourceCreator);
|
||||||
lastParamDsProcessor.setNextProcessor(headerProcessor);
|
defaultDataSourceCreator.setCreators(creators);
|
||||||
headerProcessor.setNextProcessor(sessionProcessor);
|
return defaultDataSourceCreator;
|
||||||
sessionProcessor.setNextProcessor(spelExpressionProcessor);
|
}
|
||||||
return lastParamDsProcessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取清除TTL数据源过滤器
|
* 获取数据源处理器
|
||||||
* @return 清除TTL数据源过滤器
|
*
|
||||||
*/
|
* @return 数据源处理器
|
||||||
@Bean
|
*/
|
||||||
public ClearTtlDataSourceFilter clearTtlDsFilter() {
|
@Bean
|
||||||
return new ClearTtlDataSourceFilter();
|
public DsProcessor dsProcessor(BeanFactory beanFactory) {
|
||||||
}
|
DsProcessor lastParamDsProcessor = new LastParamDsProcessor();
|
||||||
|
DsProcessor headerProcessor = new DsHeaderProcessor();
|
||||||
|
DsProcessor sessionProcessor = new DsSessionProcessor();
|
||||||
|
DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();
|
||||||
|
spelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
|
||||||
|
lastParamDsProcessor.setNextProcessor(headerProcessor);
|
||||||
|
headerProcessor.setNextProcessor(sessionProcessor);
|
||||||
|
sessionProcessor.setNextProcessor(spelExpressionProcessor);
|
||||||
|
return lastParamDsProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取清除TTL数据源过滤器
|
||||||
|
*
|
||||||
|
* @return 清除TTL数据源过滤器
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ClearTtlDataSourceFilter clearTtlDsFilter() {
|
||||||
|
return new ClearTtlDataSourceFilter();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+38
-38
@@ -24,6 +24,7 @@ import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
|
|||||||
import com.pig4cloud.pigx.common.datasource.support.DataSourceConstants;
|
import com.pig4cloud.pigx.common.datasource.support.DataSourceConstants;
|
||||||
import com.pig4cloud.pigx.common.datasource.util.DsConfTypeEnum;
|
import com.pig4cloud.pigx.common.datasource.util.DsConfTypeEnum;
|
||||||
import com.pig4cloud.pigx.common.datasource.util.DsJdbcUrlEnum;
|
import com.pig4cloud.pigx.common.datasource.util.DsJdbcUrlEnum;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jasypt.encryption.StringEncryptor;
|
import org.jasypt.encryption.StringEncryptor;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@@ -38,7 +39,9 @@ import java.util.Map;
|
|||||||
* <p>
|
* <p>
|
||||||
* 从数据源中获取 配置信息
|
* 从数据源中获取 配置信息
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JdbcDynamicDataSourceProvider extends AbstractJdbcDataSourceProvider {
|
public class JdbcDynamicDataSourceProvider extends AbstractJdbcDataSourceProvider {
|
||||||
|
|
||||||
private static final String SQL_LOG_FILTER = "sqlLogFilter";
|
private static final String SQL_LOG_FILTER = "sqlLogFilter";
|
||||||
|
|
||||||
private final DruidDataSourceProperties properties;
|
private final DruidDataSourceProperties properties;
|
||||||
@@ -62,52 +65,49 @@ public class JdbcDynamicDataSourceProvider extends AbstractJdbcDataSourceProvide
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
|
protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
|
||||||
ResultSet rs = statement.executeQuery(properties.getQueryDsSql());
|
|
||||||
|
|
||||||
Map<String, DataSourceProperty> map = new HashMap<>(8);
|
Map<String, DataSourceProperty> map = new HashMap<>(8);
|
||||||
while (rs.next()) {
|
|
||||||
String name = rs.getString(DataSourceConstants.NAME);
|
|
||||||
String username = rs.getString(DataSourceConstants.DS_USER_NAME);
|
|
||||||
String password = rs.getString(DataSourceConstants.DS_USER_PWD);
|
|
||||||
Integer confType = rs.getInt(DataSourceConstants.DS_CONFIG_TYPE);
|
|
||||||
String dsType = rs.getString(DataSourceConstants.DS_TYPE);
|
|
||||||
|
|
||||||
DataSourceProperty property = new DataSourceProperty();
|
try {
|
||||||
property.setUsername(username);
|
ResultSet rs = statement.executeQuery(properties.getQueryDsSql());
|
||||||
property.setPassword(stringEncryptor.decrypt(password));
|
|
||||||
|
|
||||||
String url;
|
while (rs.next()) {
|
||||||
// JDBC 配置形式
|
String name = rs.getString(DataSourceConstants.NAME);
|
||||||
DsJdbcUrlEnum urlEnum = DsJdbcUrlEnum.get(dsType);
|
String username = rs.getString(DataSourceConstants.DS_USER_NAME);
|
||||||
if (DsConfTypeEnum.JDBC.getType().equals(confType)) {
|
String password = rs.getString(DataSourceConstants.DS_USER_PWD);
|
||||||
url = rs.getString(DataSourceConstants.DS_JDBC_URL);
|
Integer confType = rs.getInt(DataSourceConstants.DS_CONFIG_TYPE);
|
||||||
} else {
|
String dsType = rs.getString(DataSourceConstants.DS_TYPE);
|
||||||
String host = rs.getString(DataSourceConstants.DS_HOST);
|
|
||||||
String port = rs.getString(DataSourceConstants.DS_PORT);
|
DataSourceProperty property = new DataSourceProperty();
|
||||||
String dsName = rs.getString(DataSourceConstants.DS_NAME);
|
property.setUsername(username);
|
||||||
url = String.format(urlEnum.getUrl(), host, port, dsName);
|
property.setPassword(stringEncryptor.decrypt(password));
|
||||||
|
|
||||||
|
String url;
|
||||||
|
// JDBC 配置形式
|
||||||
|
DsJdbcUrlEnum urlEnum = DsJdbcUrlEnum.get(dsType);
|
||||||
|
if (DsConfTypeEnum.JDBC.getType().equals(confType)) {
|
||||||
|
url = rs.getString(DataSourceConstants.DS_JDBC_URL);
|
||||||
|
} else {
|
||||||
|
String host = rs.getString(DataSourceConstants.DS_HOST);
|
||||||
|
String port = rs.getString(DataSourceConstants.DS_PORT);
|
||||||
|
String dsName = rs.getString(DataSourceConstants.DS_NAME);
|
||||||
|
url = String.format(urlEnum.getUrl(), host, port, dsName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Druid Config
|
||||||
|
DruidConfig druidConfig = new DruidConfig();
|
||||||
|
druidConfig.setProxyFilters(SQL_LOG_FILTER);
|
||||||
|
druidConfig.setValidationQuery(urlEnum.getValidationQuery());
|
||||||
|
property.setDruid(druidConfig);
|
||||||
|
property.setUrl(url);
|
||||||
|
|
||||||
|
map.put(name, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Druid Config
|
} catch (Exception e) {
|
||||||
DruidConfig druidConfig = new DruidConfig();
|
log.warn("动态数据源配置表异常:{}", e.getMessage());
|
||||||
druidConfig.setProxyFilters(SQL_LOG_FILTER);
|
|
||||||
druidConfig.setValidationQuery(urlEnum.getValidationQuery());
|
|
||||||
property.setDruid(druidConfig);
|
|
||||||
property.setUrl(url);
|
|
||||||
|
|
||||||
map.put(name, property);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加默认主数据源
|
|
||||||
DataSourceProperty property = new DataSourceProperty();
|
|
||||||
property.setUsername(properties.getUsername());
|
|
||||||
property.setPassword(properties.getPassword());
|
|
||||||
property.setUrl(properties.getUrl());
|
|
||||||
|
|
||||||
DruidConfig druidConfig = new DruidConfig();
|
|
||||||
druidConfig.setProxyFilters(SQL_LOG_FILTER);
|
|
||||||
property.setDruid(druidConfig);
|
|
||||||
map.put(DataSourceConstants.DS_MASTER, property);
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
* Author: lengleng (wangiegie@gmail.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.pig4cloud.pigx.common.datasource.config;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
|
||||||
|
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
|
||||||
|
import com.baomidou.dynamic.datasource.creator.druid.DruidConfig;
|
||||||
|
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.pig4cloud.pigx.common.datasource.support.DataSourceConstants.DS_MASTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lengleng
|
||||||
|
* @date 2025/1/14
|
||||||
|
* <p>
|
||||||
|
* 保证原有的 druid 配置有效性,只需要增加其他扩展数据源即可
|
||||||
|
*/
|
||||||
|
public class MasterDataSourceProvider extends AbstractDataSourceProvider {
|
||||||
|
|
||||||
|
private static final String SQL_LOG_FILTER = "sqlLogFilter";
|
||||||
|
|
||||||
|
private final DruidDataSourceProperties properties;
|
||||||
|
|
||||||
|
private final DefaultDataSourceCreator defaultDataSourceCreator;
|
||||||
|
|
||||||
|
public MasterDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator, DruidDataSourceProperties properties) {
|
||||||
|
super(defaultDataSourceCreator);
|
||||||
|
this.properties = properties;
|
||||||
|
this.defaultDataSourceCreator = defaultDataSourceCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载所有数据源
|
||||||
|
*
|
||||||
|
* @return 所有数据源,key为数据源名称
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, DataSource> loadDataSources() {
|
||||||
|
Map<String, DataSource> map = new HashMap<>();
|
||||||
|
// 添加默认主数据源
|
||||||
|
DataSourceProperty property = new DataSourceProperty();
|
||||||
|
property.setUsername(properties.getUsername());
|
||||||
|
property.setPassword(properties.getPassword());
|
||||||
|
property.setUrl(properties.getUrl());
|
||||||
|
|
||||||
|
DruidConfig druidConfig = new DruidConfig();
|
||||||
|
druidConfig.setProxyFilters(SQL_LOG_FILTER);
|
||||||
|
property.setDruid(druidConfig);
|
||||||
|
map.put(DS_MASTER, defaultDataSourceCreator.createDataSource(property));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user