Конфигурация двух источников данных в Spring Boot

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы настроить два источника данных в Spring Boot, следует предпринять следующие действия:

  1. Создать классы конфигурации и пометить их аннотацией @Configuration.
  2. Определить основную базу данных как первичную, воспользовавшись аннотацией @Primary.
  3. В файле application.properties установить параметры spring.datasource.[primary|secondary].
  4. Определить бины DataSource, применив аннотацию @ConfigurationProperties.
  5. При внедрении бина в классы использовать аннотацию @Qualifier, указывая имя dataSource.

Пример кода:

Java
Скопировать код
@Configuration
public class PrimaryConfig {
    @Primary
    @Bean
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        // Основная база данных вызвана на главную роль (покажи на что ты способна! 🎸)
        return DataSourceBuilder.create().build();
    }
}

@Configuration
public class SecondaryConfig {
    @Bean
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        // Вторичная база данных играет роль дополнительного аксессуара (без вожделенного @Primary 🤫)
        return DataSourceBuilder.create().build();
    }
}

Переменные в файле application.properties:

properties
Скопировать код
spring.datasource.primary.url=jdbc:example:primarydb
spring.datasource.secondary.url=jdbc:example:secondarydb
Кинга Идем в IT: пошаговый план для смены профессии

Освоение настроек источников данных

Настройте два источника данных в вашем приложении, учитывая детали, чтобы предотвратить конфликты и поддержать производительность.

Создание индивидуальных свойств источника данных

Для каждого DataSource можно определить собственные свойства, такие как стратегия именования сущностей или режим инициализации. Также можно указать путь к SQL-скриптам:

properties
Скопировать код
spring.datasource.primary.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.datasource.secondary.initialize=true
spring.datasource.secondary.schema=classpath:secondary-schema.sql
spring.datasource.secondary.data=classpath:secondary-data.sql

Управление транзакциями

Управление транзакциями между различными базами данных может быть реализовано при помощи ChainedTransactionManager или индивидуального DataSourceTransactionManager для каждой базы:

Java
Скопировать код
@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager primaryTransactionManager = new JpaTransactionManager(primaryEntityManagerFactory().getObject());
    DataSourceTransactionManager secondaryTransactionManager = new DataSourceTransactionManager(secondaryDataSource());

    // Отличный выбор, когда требуется управление несколькими транзакциями одновременно 🕴️
    return new ChainedTransactionManager(primaryTransactionManager, secondaryTransactionManager);
}

При работе с транзакциями нужно указывать имя менеджера транзакций при помощи аннотации @Transactional("transactionManagerName").

Настройка отдельных EntityManager’ов

Настроить отдельные экземпляры EntityManagerFactory для каждого источника данных, при этом важно учитывать аннотации @Primary и @Qualifier для определения нужных компонентов:

Java
Скопировать код
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier("primaryDataSource") DataSource dataSource) {
    // Здесь начинается погружение в мир основной базы данных 🏊‍♀️
    return builder
            .dataSource(dataSource)
            .packages("com.example.primary")
            .persistenceUnit("primary")
            .build();
}

@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier("secondaryDataSource") DataSource dataSource) {
    // Вторичная база данных, хоть и в роли дополнения, также играет свою роль! 😂
    return builder
            .dataSource(dataSource)
            .packages("com.example.secondary")
            .persistenceUnit("secondary")
            .build();
}

Разделение репозиториев

Spring Data предлагает возможность разделения репозиториев между разными источниками данных и связанными с ними EntityManager’ами:

Java
Скопировать код
@Configuration
@EnableJpaRepositories(
  basePackages = "com.example.primary",
  entityManagerFactoryRef = "primaryEntityManagerFactory",
  transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDataSourceConfiguration {
  // ...
}

@Configuration
@EnableJpaRepositories(
  basePackages = "com.example.secondary",
  entityManagerFactoryRef = "secondaryEntityManagerFactory",
  transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDataSourceConfiguration {
  // ...
}

Инициализация баз данных

Подготовьте базы данных к использованию, определев DDL и DML скрипты для каждого источника данных.

Управление зависимостями

Проверьте настройку зависимостей в pom.xml, чтобы обеспечить поддержку нескольких источников данных. Особое внимание следует уделить транзакционности и параллелизму.

Движение к более сложным настройкам

Воспользуйтесь более продвинутыми настройками Kotlin, Spring Boot и Hibernate, чтобы достичь наиболее точной конфигурыации для эффективной работы приложения.

Визуализация

Представьте себе, что ваше приложение это шеф-повар (👨‍🍳), который готовит изысканное блюдо из продуктов, взятых из двух разных кладовых:

Markdown
Скопировать код
Кладовая A (🗄️): Основные настройки источника данных   (🐟)
Кладовая B (🗃️): Вторичные настройки источника данных (🌿)

Для приготовления удивительного блюда, шеф-повар мастерски манипулирует ингредиентами из обоих кладовых:

Markdown
Скопировать код
👨‍🍳⚙️🗄️: Основные компоненты в приоритете, используем @Primary (🐟)

Основные ингредиенты ложатся в основу блюда.

Markdown
Скопировать код
👨‍🍳⚙️🗃️: Для дополнительных акцентов воспользуемся @Bean (🌿)

Дополнительные детали добавляют изысканность и завершают блюдо.

И вот, приложение искусно сочетает элементы из обеих кладовых, предоставляя потрясающий пользовательский опыт.

Решения возможных проблем проекта

Работая с несколькими источниками данных, возможно столкновение с некоторыми трудностями. Однако их можно преодолеть путем профилактики и внимательного подхода:

Осторожность при настройке источника данных

Тщательно настраивайте свойства каждого источника данных, чтобы предотвратить пересечение и обеспечить уникальность конфигураций.

Предотвращение неправильного управления транзакциями

Ошибки при настройке транзакций могут привести к проблемам синхронизации и потери данных. Правильно разграничивайте и квалифицируйте транзакции, особенно в сложных случаях, при помощи ChainedTransactionManager.

Избегание проблем с "ленивой" загрузкой

"Ленивая" загрузка может вызвать нежелательные последствия. Обеспечьте правильное управление прокси-серверами и транзакциями для поддержки ленивой инициализации.

Обеспечение управления

При работе с несколькими базами данных, учитывайте безопасность и мультипользовательскую среду, чтобы сохранить данные в целостности и изоляции.

Полезные материалы

  1. Настройка нескольких баз данных в Spring Boot | DevGlan — замечательное руководство по настройке нескольких баз данных.
  2. Официальная документация Spring Boot — подробное описание функционала доступа к данным в Spring Boot.
  3. Динамическая маршрутизация источников данных — углубленные знания о маршрутизации источников данных.
  4. Java Development Journal — сайт с большим количеством статей по Java-разработке, включая работу с несколькими базами данных.
  5. Несколько источников данных в Spring Boot | Baeldung — подробное руководство по конфигурации множественных источников данных в Spring Boot.