Использование базы данных для модуля

В статье упоминаются классы и файлы:

  • SDKSpringModuleConfigurationConstants = ИмяВашегоМодуляConfigurationConstants

  • SDKSpringConfigurationProperty = ИмяВашегоМодуляConfigurationProperty

  • SDKSpringModule = ИмяВашегоМодуляModule

  • SDKSpringMigrations = ИмяВашегоМодуляMigrations

Настройка БД

В файле SDKSpringModuleConfigurationConstants заданы константы SDK_SPRING_SCHEMA_NAME и SDK_SPRING_LOG_NAME: в SDK_SPRING_SCHEMA_NAME - имя схемы в базе данных, в SDK_SPRING_LOG_NAME - имя таблицы, где хранится история миграций.

Дополнительно в файле backend.properties необходимо указать настройки Module.ID + имя базы данных из SDK_SPRING_SCHEMA_NAME.

В примере Module.ID заменен на SDKSpringModule.ID из проекта-примера, а currentSchema на SDKSpringModuleConfigurationConstants.SDK_SPRING_SCHEMA_NAME.

currentSchema также содержит public, т.к. все плагины устанавливаются в схему public.

Если расширение необходимо конкретному модулю, он миграцией запускает код create extension <X> if not exists.., не полагаясь на то, что некий другой модуль уже установил это расширение.

com.universe.mdm.sdk.spring.datasource.url=jdbc:postgresql://POSTGRES_ADDRESS/DATABASE_NAME?user=POSTGRES_USERNAME&password=POSTGRES_PASSWORD&currentSchema=com_universe_mdm_sdk_spring,public&reWriteBatchedInserts=true&ApplicationName=UNIVERSE-SDK-SPRING
com.universe.mdm.sdk.spring.datasource.uniqueName=UNIVERSE-SDK-SPRING
com.universe.mdm.sdk.spring.datasource.minPoolSize = 3
com.universe.mdm.sdk.spring.datasource.maxPoolSize = 10

Добавление библиотеки

Добавьте nl.myndocs:database-migrator в конфигурационный файл сборки.

Создание коннектора

Для создания коннектора создайте бин:

@Configuration
public class SDKSpringConfiguration extends ModuleConfiguration {

    @Bean(name = "sdkSpringDataSource")
    public DataSource sdkSpringDataSource() {
        Properties properties = getPropertiesByPrefix(SDKSpringModule.MODULE_ID + ".datasource.", true);
        return DataSourceUtils.newPoolingXADataSource(properties);
    }

Управление структурой базы данных

Работа со структурой БД происходит с помощью библиотеки nl.myndocs.database.migrator.

Все миграции находятся в директории resources/migration/.

Миграции подключаются в S``DKSpringModule`` (если это миграции, необходимые для установки/обновления модуля) или вызываются в ином месте. Об используемых переменных см. Переменные конфигурации для модуля-примера.

  1. Например, модуль хочет хранить описание солнечной системы в базе данных. Для этого в директории resources/migration/ создается sql файл с уникальным для модуля именем, например, init_sdk_module.sql.

CREATE TABLE solar_system
(
    id          serial PRIMARY KEY,
    planet_name text,
    is_planet   bool
);
INSERT INTO solar_system(planet_name, is_planet)
VALUES ('Venus', true),('Earth', true),('Sun', false);
  1. Далее в класс migration/SDKSpringMigrations добавляется описание миграций:

package com.universe.mdm.sdk.spring.migration;

import org.unidata.mdm.system.migration.Migrations;
import org.unidata.mdm.system.util.ResourceUtils;
import nl.myndocs.database.migrator.MigrationScript;

public class SDKSpringMigrations {

    private SDKSpringMigrations() {

    }

    private static final MigrationScript[] INSTALL = {

            Migrations.of("init_sdk_migration",
                    "sdk.module.author",
                    ResourceUtils.asString("classpath:/migration/init_sdk_module.sql"))

    };

    public static MigrationScript[] migrations() {
        return INSTALL;
    }
}
  1. Затем, используя бин sdkSpringDataSource в SDKSpringModule, на стадии install() модуля вызовите миграцию:

public class SDKSpringModule extends AbstractModule {

    @Autowired
    private DatabaseMigrationService databaseMigrationService;

    @Autowired
    @Qualifier("sdkSpringDataSource")
    private DataSource sdkSpringDataSource;

    private boolean install;


    @Override
    public void install() {
        LOGGER.info("Install");
        if(!install){
            migrate();
        }
    }

    @Override
    public void start() {
        LOGGER.info("Starting...");
        install = true;
        LOGGER.info("Started");
    }

    private void migrate() {
        DatabaseMigrationContext ctx = DatabaseMigrationContext.builder()
                .schemaName(SDKSpringModuleConfigurationConstants.SDK_SPRING_SCHEMA_NAME)
                .logName(SDKSpringModuleConfigurationConstants.SDK_SPRING_LOG_NAME)
                .dataSource(sdkSpringDataSource)
                .migrations(SDKSpringMigrations.migrations())
                .build();

        databaseMigrationService.migrate(ctx);
    }

Ожидаемый результат после старта системы:

  • Создана схема с именем SDKSpringModuleConfigurationConstants.SDK_SPRING_SCHEMA_NAME.

  • В указанной в настройках базе данных в схеме модуля созданы 2 таблицы:

    • Таблица SDKSpringModuleConfigurationConstants.SDK_SPRING_LOG_NAME с одной записью о миграции.

    • Таблица solar_system из миграции init_sdk_module.sql с тремя записями.