在 Spring 引导中使用两个数据源
Using two datasources in Spring Boot
我在我的项目中使用 Spring Boot 1.3.3
和 一个 数据库,现在我想使用两个具有 相同架构 [=19] 的数据库=] 但 不同的连接 .
我想使用相同的存储库、实体,并根据情况找到告诉spring我想使用哪个数据源的方法。
如果有人遇到这个问题,我已经找到了解决方案:
首先你的application.properties应该是这样的:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
之后,您必须使用您的数据库创建一个枚举:
public enum Database {
PRIMARY,
SECONDARY
}
然后,你创建一个ThreadLocal:
public class DatabaseThreadContext {
private static final ThreadLocal<Database> current = new ThreadLocal<>();
public static void setCurrentDatabase(Database database) {
current.set(database);
}
public static Object getCurrentDatabase() {
return current.get();
}
}
魔法来了,你必须使用 AbstractRoutingDataSource,它在 2007 年的 Spring 2 中实现:
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseThreadContext.getCurrentDatabase();
}
}
最后在您的 Spring 引导应用程序中注入一个配置:
@Configuration
public class DatabaseRouter {
@Bean
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DataSource dataSource() {
Map<Object, Object> targetDatasources = new HashMap<Object, Object>(){{
put(Database.SECONDARY, secondaryDataSource());
put(Database.PRIMARY, primaryDataSource());
}};
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(primaryDataSource());
routingDataSource.setTargetDataSources(targetDatasources);
routingDataSource.afterPropertiesSet();
return routingDataSource;
}
}
在每个请求中,如果您想在数据库之间切换,只需使用此功能:DatabaseThreadContext.setCurrentDatabase(Database.PRIMARY);
。
此外,您可以同时拥有两个以上的数据库。
我在我的项目中使用 Spring Boot 1.3.3
和 一个 数据库,现在我想使用两个具有 相同架构 [=19] 的数据库=] 但 不同的连接 .
我想使用相同的存储库、实体,并根据情况找到告诉spring我想使用哪个数据源的方法。
如果有人遇到这个问题,我已经找到了解决方案:
首先你的application.properties应该是这样的:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db
username: your_username
password: your_password
driver-class-name: com.mysql.jdbc.Driver
之后,您必须使用您的数据库创建一个枚举:
public enum Database {
PRIMARY,
SECONDARY
}
然后,你创建一个ThreadLocal:
public class DatabaseThreadContext {
private static final ThreadLocal<Database> current = new ThreadLocal<>();
public static void setCurrentDatabase(Database database) {
current.set(database);
}
public static Object getCurrentDatabase() {
return current.get();
}
}
魔法来了,你必须使用 AbstractRoutingDataSource,它在 2007 年的 Spring 2 中实现:
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseThreadContext.getCurrentDatabase();
}
}
最后在您的 Spring 引导应用程序中注入一个配置:
@Configuration
public class DatabaseRouter {
@Bean
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DataSource dataSource() {
Map<Object, Object> targetDatasources = new HashMap<Object, Object>(){{
put(Database.SECONDARY, secondaryDataSource());
put(Database.PRIMARY, primaryDataSource());
}};
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(primaryDataSource());
routingDataSource.setTargetDataSources(targetDatasources);
routingDataSource.afterPropertiesSet();
return routingDataSource;
}
}
在每个请求中,如果您想在数据库之间切换,只需使用此功能:DatabaseThreadContext.setCurrentDatabase(Database.PRIMARY);
。
此外,您可以同时拥有两个以上的数据库。