refactor(common-datasource): 重构动态数据源,同支持 YAML + JDBC ,兼容Druid 标准配置

This commit is contained in:
冷冷 committed 2025-03-09 21:10:31 +08:00
1 parent 4cb2e1ceae
commit f97295cef1
3 files changed
+175 -87

No files matched your search

@@ -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();
}
} }
@@ -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;
} }
@@ -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;
}
}