All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lx.boot.db.DynamicDataSource Maven / Gradle / Ivy

Go to download

使用文档: https://a7fi97h1rc.feishu.cn/docx/X3LRdtLhkoXQ8hxgXDQc2CLOnEg?from=from_copylink

There is a newer version: 1.1
Show newest version
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