com.lx.boot.db.DynamicDataSource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lxboot3 Show documentation
Show all versions of lxboot3 Show documentation
使用文档: https://a7fi97h1rc.feishu.cn/docx/X3LRdtLhkoXQ8hxgXDQc2CLOnEg?from=from_copylink
package com.lx.boot.db;
import com.lx.boot.OS;
import com.lx.constant.DefaultBaseConstant;
import com.lx.entity.CustomDbInfo;
import com.lx.util.LX;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 动态数据源实现类
* @author ylx
* db.host 数据库地址
* db.name 数据库名称(默认项目名)
* db.user 数据库用户
* db.pass 数据库密码
*/
@Slf4j
@Component
@ConditionalOnProperty(name = DefaultBaseConstant.DB_ENABLE, havingValue = "true", matchIfMissing = true)
public class DynamicDataSource extends AbstractRoutingDataSource implements BeanPostProcessor {
public DynamicDataSource(){
setTargetDataSources(new HashMap<>());
}
/** 用来缓存dataSource*/
private final static Map dataSourceMap = new HashMap<>();
/**
* 如果不希望数据源在启动配置时就加载好,可以定制这个方法,从任何你希望的地方读取并返回数据源
* 比如从数据库、文件、外部接口等读取数据源信息,并最终返回一个DataSource实现类对象即可
*/
@Override
protected DataSource determineTargetDataSource() {
return getDataSource();
}
//说明:生成数据源
/**{ ylx } 2020/8/31 17:10 */
public DataSource getDataSource() {
//获取当前线程的医院对应的数据源 business 和 dictionary 其他获取公司数据源
CustomDbInfo customDbInfo = OS.getCustomDbInfo();
if (LX.isEmpty(customDbInfo)){
String url = OS.getProperty(DefaultBaseConstant.DB_CUSTOM_URL);
LX.exObj(url,"["+DefaultBaseConstant.DB_CUSTOM_URL+"]数据源URL没有配置!");
//适用于多项目使用一个nacos分别使用不同数据库时
String dbName = OS.getProperty("db.name."+OS.getApplicationName());
if (LX.isNotEmpty(dbName)){
url+=dbName;
}
String username = OS.getProperty(DefaultBaseConstant.DB_USERNAME);
String password = OS.getProperty(DefaultBaseConstant.DB_PASSWORD);
customDbInfo = new CustomDbInfo(url, username, password);
}
String url = customDbInfo.getUrl();
if (!url.contains("jdbc:")){
url = "jdbc:mysql://"+url+"?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true";
customDbInfo.setUrl(url);
}
//默认数据源
log.info("切换到数据源:"+url);
String md5 = LX.md5(customDbInfo.getUrl() + customDbInfo.getUsername() + customDbInfo.getPassword());
if (dataSourceMap.containsKey(md5)){
return dataSourceMap.get(md5);
}
//创建datasource
DataSourceBuilder> builder = DataSourceBuilder.create();
DataSourceBuilder dbuilder = builder.type(HikariDataSource.class);
builder.url(customDbInfo.getUrl());
builder.username(customDbInfo.getUsername());
builder.password(customDbInfo.getPassword());
//解决特殊字符问题
HikariDataSource dataSource = dbuilder.build();
dataSource.setConnectionInitSql(OS.getProperty("db.connectionInitSql","SET NAMES utf8mb4"));
dataSourceMap.put(md5,dataSource);
return dataSource;
}
/**
* 如果希望所有数据源在启动配置时就加载好,这里通过设置数据源Key值来切换数据,定制这个方法
*/
@Override
protected Object determineCurrentLookupKey() {
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy