Краткое руководство по загрузке исходных данных с помощью Spring Boot

Краткое руководство по загрузке исходных данных с помощью Spring Boot

1. обзор

Spring Boot позволяет легко и просто управлять изменениями в нашей базе данных. Если мы оставим конфигурацию по умолчанию, он будет искать объекты в наших пакетах и ​​автоматически создавать соответствующие таблицы.

Но иногда нам может потребоваться более тонкий контроль над изменениями базы данных. Вот тогда мы можем использовать файлыdata.sql иschema.sql в Spring.

2. Файлdata.sql

Давайте также сделаем предположение, что мы работаем с JPA, и определим простую сущностьCountry в нашем проекте:

@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Integer id;

    @Column(nullable = false)
    private String name;

    //...
}

Если мы запустим наше приложение,Spring Boot will create an empty table for us, but won’t populate it with anything.

Легкий способ сделать это - создать файл с именемdata.sql:

INSERT INTO country (name) VALUES ('India');
INSERT INTO country (name) VALUES ('Brazil');
INSERT INTO country (name) VALUES ('USA');
INSERT INTO country (name) VALUES ('Italy');

Когда мы запустим проект с этим файлом в classpath, Spring подберет его и будет использовать для заполнения базы данных.

3. Файлschema.sql

Иногда мы не хотим полагаться на механизм создания схемы по умолчанию. В таких случаях мы можем создать собственный файлschema.sql:

CREATE TABLE country (
    id   INTEGER      NOT NULL AUTO_INCREMENT,
    name VARCHAR(128) NOT NULL,
    PRIMARY KEY (id)
);

Spring подберет этот файл и использует его для создания схемы.

Также важно не забыть отключить автоматическое создание схемы, чтобы избежать конфликтов:

spring.jpa.hibernate.ddl-auto=none

4. Управление созданием базы данных с помощью гибернации

Spring предоставляет специфичный для JPAproperty which Hibernate uses for DDL generation:*spring.jpa.hibernate.ddl-auto*.

Стандартные значения свойств Hibernate:create,update,create-drop,validate иnone:

  • create - Hibernate сначала удаляет существующие таблицы, а затем создает новые таблицы

  • update - объектная модель, созданная на основе сопоставлений (аннотаций или XML), сравнивается с существующей схемой, а затем Hibernate обновляет схему в соответствии с diff. Он никогда не удаляет существующие таблицы или столбцы, даже если они больше не требуются приложению

  • create-drop - аналогcreate, с той лишь разницей, что Hibernate удалит базу данных после завершения всех операций. Обычно используется для модульного тестирования

  • validate - Hibernate только проверяет, существуют ли таблицы и столбцы, иначе выдает исключение.

  • none - это значение эффективно отключает генерацию DDL

Spring Boot внутренне устанавливает значение этого параметра по умолчанию наcreate-drop, если диспетчер схемы не был обнаружен, в противном случаеnone для всех остальных случаев.

Нам нужно тщательно установить значение или использовать один из других механизмов для инициализации базы данных.

5. @Sqlс

Spring также предоставляет аннотацию@Sql - декларативный способ инициализации и заполнения нашей тестовой схемы.

Давайте посмотрим, как использовать аннотацию@Sql для создания новой таблицы, а также загрузить в таблицу исходные данные для нашего интеграционного теста:

@Sql({"/employees_schema.sql", "/import_employees.sql"})
public class SpringBootInitialLoadIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestClass() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

Атрибуты аннотации@Sql:

  • config – локальная конфигурация для сценариев SQL. Мы опишем это подробно в следующем разделе

  • executionPhase –, мы также можем указать, когда выполнять скрипты:BEFORE_TEST_METHOD илиAFTER_TEST_METHOD

  • statements – we может объявлять встроенные операторы SQL для выполнения

  • scripts – we может объявлять пути к файлам сценариев SQL для выполнения. Это псевдоним атрибутаvalue 

Аннотация@Sqlcan be used at the class level or the method level. Мы можем загрузить дополнительные данные, необходимые для конкретного тестового примера, пометив этот метод:

@Test
@Sql({"/import_senior_employees.sql"})
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

6. @SqlConfigс

Мы можемconfigure the way we parse and run the SQL scripts, используя аннотацию@SqlConfig.

@SqlConfig можно объявить на уровне класса, где он служит глобальной конфигурацией. Или его можно использовать для настройки конкретной аннотации@Sql.

Давайте посмотрим на пример, в котором мы указываем кодировку наших сценариев SQL, а также режим транзакции для выполнения сценариев:

@Test
@Sql(scripts = {"/import_senior_employees.sql"},
  config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED))
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

И давайте посмотрим на различные атрибуты@SqlConfig:

  • blockCommentStartDelimiter - разделитель для обозначения начала комментариев блока в файлах сценария SQL

  • blockCommentEndDelimiter - разделитель для обозначения конца комментариев блока в файлах сценария SQL

  • commentPrefix - префикс для обозначения однострочных комментариев в файлах сценария SQL

  • dataSource - имя bean-компонентаjavax.sql.DataSource, для которого будут запускаться скрипты и операторы

  • encoding - кодировка для файлов сценария SQL, по умолчанию кодировка платформы

  • errorMode - режим, который будет использоваться при обнаружении ошибки при запуске скриптов

  • separator - строка, используемая для разделения отдельных операторов, по умолчанию «-»

  • transactionManager - имя bean-компонентаPlatformTransactionManager , который будет использоваться для транзакций

  • transactionMode - режим, который будет использоваться при выполнении скриптов в транзакции

7. @SqlGroupс

Java 8 и выше позволяют использовать повторные аннотации. Эту функцию также можно использовать для аннотаций@Sql. Для Java 7 и ниже существует аннотация контейнера -@SqlGroup. Using the @SqlGroup annotation, we can declare multiple @Sql annotations:

@SqlGroup({
  @Sql(scripts = "/employees_schema.sql",
    config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)),
  @Sql("/import_employees.sql")})
public class SpringBootSqlGroupAnnotationIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestCase() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

8. Заключение

В этой быстрой статье мы увидели, как мы можем использовать файлыschema.sql иdata.sql для настройки начальной схемы и заполнения ее данными. Мы также увидели, как мы можем использовать аннотации@Sql, @SqlConfig и@SqlGroup для загрузки тестовых данных для тестов.

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

Фрагменты кода, как всегда, можно найтиover on GitHub.