Если кто имеет эту проблему, я нашел решение:
Первого вашего 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, который был реализован весной 2 еще в 2007 году:
public class RoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DatabaseThreadContext.getCurrentDatabase();
}
}
Наконец впрыснуть конфигурации в Спринг загрузки приложения:
@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);
.
Кроме того, вы можете иметь более двух баз данных одновременно.
Используйте активные профили пружины в application.yml –
@ Zubair Я хочу использовать оба одновременно, и в зависимости от ситуации в моей службе выберите тот или иной. –
@JeanCedron Это сложная настройка. Не уклониться от вопроса, но подумали ли вы об использовании слоя обмена сообщениями для его устранения? Приложение Decider принимает решение о том, какой ресурс данных должен сохраняться. Затем он отправляет сообщение в конкретную очередь данных, для которой рабочий узел считывает и сохраняет данные. Просто мысль ... Я сделал несколько приложений с двумя источниками данных, но они были полностью разделены на пакеты по отношению к объектам, репозиториям и т. Д. –