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.