Guia rápido sobre o carregamento de dados iniciais com o Spring Boot

Guia rápido sobre o carregamento de dados iniciais com o Spring Boot

1. Visão geral

O Spring Boot facilita muito o gerenciamento das alterações no banco de dados de maneira fácil. Se deixarmos a configuração padrão, ele pesquisará entidades em nossos pacotes e criará as respectivas tabelas automaticamente.

Mas às vezes precisamos de algum controle mais refinado sobre as alterações do banco de dados. É quando podemos usar os arquivosdata.sqleschema.sql no Spring.

2. O arquivodata.sql

Vamos também supor que estamos trabalhando com JPA - e definir uma entidadeCountry simples em nosso projeto:

@Entity
public class Country {

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

    @Column(nullable = false)
    private String name;

    //...
}

Se executarmos nosso aplicativo,Spring Boot will create an empty table for us, but won’t populate it with anything.

Uma maneira fácil de fazer isso é criar um arquivo chamadodata.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');

Quando executamos o projeto com esse arquivo no caminho de classe, o Spring o seleciona e o utiliza para preencher o banco de dados.

3. O arquivoschema.sql

Às vezes, não queremos contar com o mecanismo de criação de esquema padrão. Nesses casos, podemos criar um arquivoschema.sql personalizado:

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

O Spring selecionará esse arquivo e o utilizará para criar um esquema.

Também é importante lembrar de desligar a criação automática de esquema para evitar conflitos:

spring.jpa.hibernate.ddl-auto=none

4. Controlando a criação do banco de dados usando o Hibernate

Spring fornece umproperty which Hibernate uses for DDL generation:*spring.jpa.hibernate.ddl-auto*. específico de JPA

Os valores padrão das propriedades do Hibernate são:create,update,create-drop,validate enone:

  • create - o Hibernate primeiro elimina as tabelas existentes, depois cria novas tabelas

  • update - o modelo de objeto criado com base nos mapeamentos (anotações ou XML) é comparado com o esquema existente, e então o Hibernate atualiza o esquema de acordo com o diff. Ele nunca exclui as tabelas ou colunas existentes, mesmo que elas não sejam mais necessárias pelo aplicativo.

  • create-drop - semelhante acreate, com a adição de que o Hibernate irá eliminar o banco de dados após todas as operações serem concluídas. Normalmente usado para teste de unidade

  • validate - o Hibernate só valida se as tabelas e colunas existem, caso contrário, ele lança uma exceção

  • none - este valor desativa efetivamente a geração de DDL

O Spring Boot padroniza internamente este valor de parâmetro paracreate-drop se nenhum gerenciador de esquema foi detectado, caso contrário,none para todos os outros casos.

Temos que definir o valor com cuidado ou usar um dos outros mecanismos para inicializar o banco de dados.

5. @Sql

Spring também fornece a anotação@Sql - uma forma declarativa de inicializar e preencher nosso esquema de teste.

Vamos ver como usar a anotação@Sql para criar uma nova tabela e também carregar a tabela com os dados iniciais para nosso teste de integração:

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

    @Autowired
    private EmployeeRepository employeeRepository;

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

Os atributos da anotação@Sql são:

  • config – configuração local para os scripts SQL. Descrevemos isso em detalhes na próxima seção

  • executionPhase – também podemos especificar quando executar os scripts, sejaBEFORE_TEST_METHOD ouAFTER_TEST_METHOD

  • statements – we pode declarar instruções SQL embutidas para executar

  • scripts – we pode declarar os caminhos para os arquivos de script SQL a serem executados. Este é um alias para ovalue attribute

A anotação@Sqlcan be used at the class level or the method level. Podemos carregar dados adicionais necessários para um caso de teste específico, anotando esse método:

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

6. @SqlConfig

Podemosconfigure the way we parse and run the SQL scripts usando a anotação@SqlConfig.

@SqlConfig pode ser declarado no nível da classe, onde serve como uma configuração global. Ou pode ser usado para configurar uma anotação de@Sql particular.

Vejamos um exemplo onde especificamos a codificação de nossos scripts SQL, bem como o modo de transação para a execução dos scripts:

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

E vamos dar uma olhada nos vários atributos de@SqlConfig:

  • blockCommentStartDelimiter - delimitador para identificar o início dos comentários do bloco em arquivos de script SQL

  • blockCommentEndDelimiter - delimitador para denotar o fim dos comentários do bloco em arquivos de script SQL

  • commentPrefix - prefixo para identificar comentários de uma única linha em arquivos de script SQL

  • dataSource - nome do beanjavax.sql.DataSource contra o qual os scripts e instruções serão executados

  • encoding - codificação para os arquivos de script SQL, o padrão é codificação de plataforma

  • errorMode - modo que será usado quando for encontrado um erro ao executar os scripts

  • separator - string usada para separar instruções individuais, o padrão é “-“

  • transactionManager - nome do bean dePlatformTransactionManager que será usado para transações

  • transactionMode - o modo que será usado ao executar scripts na transação

7. @SqlGroup

O Java 8 e superior permitem o uso de anotações repetidas. Este recurso também pode ser utilizado para anotações de@Sql. Para Java 7 e anteriores, há uma anotação de contêiner -@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. Conclusão

Neste artigo rápido, vimos como podemos aproveitar os arquivosschema.sqledata.sql para configurar um esquema inicial e preenchê-lo com dados. Também vimos como podemos usar as anotações@Sql, @SqlConfig e@SqlGroup para carregar dados de teste para testes.

Lembre-se de que essa abordagem é mais adequada para cenários básicos e simples, qualquer manipulação avançada de banco de dados exigiria ferramentas mais avançadas e refinadas, comoLiquibase ouFlyway.

Trechos de código, como sempre, podem ser encontradosover on GitHub.