【Spring-Data】JDBC

JDBC 多数据源实现

参考:https://cloud.tencent.com/developer/article/2186673

Springboot 中使用 JdbcTemplate 实现多数据源比较简单。查看 JdbcTemplate 源码;可以发现 JdbcTemplate 提供了传入 DataSource 的方式构建不同的 JdbcTemplate 实例。通过该方式就可以实现多数据源。

引入:spring-boot-starter-jdbc,mysql 的POM依赖

1、定义2个数据源的配置,前缀不同

2、定义 DataSourceConfig,实现2个DataSource bean(传入不同的@ConfigurationProperties(prefix=xxx)

3、定义 JdbcTemplateConfig,定义2个JdbcTemplate,传入不同的Datasource实例

4、定义不同的Repository,传入不同的JdbcTemplate

 

动态数据源切换

https://www.jianshu.com/p/a042ff2ee2ae

实现数据源切换的功能就是自定义一个类扩展AbstractRoutingDataSource抽象类,其实该相当于数据源DataSourcer的路由中介,可以实现在项目运行时根据相应key值切换到对应的数据源DataSource上。

方法里使用到了determineCurrentLookupKey()方法,它是AbstractRoutingDataSource类的抽象方法,也是实现数据源切换要扩展的方法,该方法的返回值就是项目中所要用的DataSource的key值,拿到该key后就可以在resolvedDataSource中取出对应的DataSource,如果key找不到对应的DataSource就使用默认的数据源。

AbstractRoutingDatasource

参考:https://www.baeldung.com/spring-abstract-routing-data-source

1、Datasource Context

AbstractRoutingDatasource requires information to know which actual DataSource to route to. This information is typically referred to as Context.

2、Context Holder

It’s critically important to use ThreadLocal here so that the context is bound to the currently executing thread.

复制代码
public class ClientDatabaseContextHolder {
    private static ThreadLocal<ClientDatabase> CONTEXT  = new ThreadLocal<>();
    public static void set(ClientDatabase clientDatabase) {
        Assert.notNull(clientDatabase, "clientDatabase cannot be null");
        CONTEXT.set(clientDatabase);
    }
    public static ClientDatabase getClientDatabase() {
        return CONTEXT.get();
    }
    public static void clear() {
        CONTEXT.remove();
    }
}
复制代码

3、Datasource Router

We define our ClientDataSourceRouter to extend the Spring AbstractRoutingDataSource. We implement the necessary determineCurrentLookupKey method to query our ClientDatabaseContextHolder and return the appropriate key.

The AbstractRoutingDataSource implementation handles the rest of the work for us and transparently returns the appropriate DataSource:

public class ClientDataSourceRouter extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return ClientDatabaseContextHolder.getClientDatabase();
    }
}

4、

We need a Map of contexts to DataSource objects to configure our AbstractRoutingDataSource. We can also specify a default DataSource if there is no context set.

The DataSources we use can come from anywhere but will typically be either created at runtime or looked up using JNDI:

复制代码
@Configuration
public class RoutingTestConfiguration {
    @Bean
    public ClientService clientService() {
        return new ClientService(new ClientDao(clientDatasource()));
    }
    @Bean
    public DataSource clientDatasource() {
        Map<Object, Object> targetDataSources = new HashMap<>();
        DataSource clientADatasource = clientADatasource();
        DataSource clientBDatasource = clientBDatasource();
        targetDataSources.put(ClientDatabase.CLIENT_A, clientADatasource);
        targetDataSources.put(ClientDatabase.CLIENT_B, clientBDatasource);

        ClientDataSourceRouter clientRoutingDatasource = new ClientDataSourceRouter();
        clientRoutingDatasource.setTargetDataSources(targetDataSources);
        clientRoutingDatasource.setDefaultTargetDataSource(clientADatasource);
        return clientRoutingDatasource;
    }
}
复制代码

5、定义2个不同的datasource,参考文章顶部的类似定义

 

posted @   飞翔在天  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示