Prof. Me. Danilo Bueno
List
Um reinício de servidor, uma queda de energia ou um redeploy têm o mesmo efeito.
[ Aplicação Spring Boot ] ──── conexão de rede ────▶ [ Banco de dados ] dados somem ao reiniciar dados sobrevivem
O banco de dados roda como um processo independente, com armazenamento próprio em disco.
tabela: produto ┌────┬──────────────┬────────┐ │ id │ nome │ preco │ ├────┼──────────────┼────────┤ │ 1 │ Espresso │ 6.00 │ │ 2 │ Cappuccino │ 9.00 │ └────┴──────────────┴────────┘
id
É por meio da chave primária que outras partes do sistema se referem a um registro específico, sem ambiguidade.
docker run --name cafeteria-mysql \ -e MYSQL_ROOT_PASSWORD=cafeteria \ -e MYSQL_DATABASE=cafeteria \ -p 3306:3306 \ -d mysql:8
O MySQL roda como um processo separado da aplicação Java; por isso precisa do Docker.
docker exec -it cafeteria-mysql mysql -uroot -pcafeteria cafeteria
SHOW TABLES;-- Empty set
O banco existe; a aplicação Java ainda não sabe disso.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope></dependency>
O starter-jdbc traz a classe JdbcTemplate, usada apenas a partir da próxima aula.
starter-jdbc
JdbcTemplate
jdbc:mysql://localhost:3306/cafeteria └───┬───┘ └┬─┘ └───┬───┘ host porta banco
A mesma anatomia de URL estudada na primeira semana: host, porta e caminho.
spring.datasource.url=jdbc:mysql://localhost:3306/cafeteriaspring.datasource.username=rootspring.datasource.password=cafeteria
application.properties guarda a senha em texto puro: aceitável só em ambiente de estudo.
application.properties
Um mesmo esquema precisa ser recriado, na mesma ordem, em cada ambiente: o do desenvolvedor, o de testes, o de produção.
Sem essa disciplina, é fácil um ambiente ficar com uma estrutura diferente dos demais.
Garante que todo ambiente (desenvolvimento, testes, produção) passe exatamente pelas mesmas migrações, na mesma ordem, e chegue ao mesmo esquema.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-flyway</artifactId></dependency><dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-mysql</artifactId></dependency>
Assim como o driver do MySQL, o Flyway é só mais uma biblioteca: nenhum processo, nenhuma instalação separada. O starter do Spring Boot já configura o Flyway automaticamente com o DataSource da aplicação.
DataSource
Creating Schema History table `cafeteria`.`flyway_schema_history` ... Successfully applied 0 migrations to schema `cafeteria`
db/migration/ ├── V1__criar_tabela_produto.sql └── V2__criar_tabela_pedido.sql
O Flyway localiza esses arquivos pela convenção de nome, sem nenhuma configuração adicional.
V1__criar_tabela_produto.sql └┬┘ └──────────┬───────────┘ │ descrição versão
V
__
O Flyway ordena e identifica cada migração só pelo nome do arquivo: renomear uma migração já aplicada altera seu checksum e quebra a conferência.
-- V1__criar_tabela_produto.sqlCREATE TABLE produto ( id BIGINT AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(255) NOT NULL, preco DECIMAL(10,2) NOT NULL);
A coluna id, autoincrementada, é a chave primária: identifica cada linha sem ambiguidade.
-- V2__criar_tabela_pedido.sqlCREATE TABLE pedido ( id BIGINT AUTO_INCREMENT PRIMARY KEY, nome_cliente VARCHAR(255) NOT NULL, quantidade INT NOT NULL);
As duas migrações são aplicadas em ordem, na próxima vez que a aplicação subir.
SHOW TABLES;-- produto, pedido, flyway_schema_historySELECT * FROM flyway_schema_history;-- V1 e V2, cada uma com seu checksum
A aplicação e o banco agora existem lado a lado, ainda sem nenhuma ligação entre eles.
flyway_schema_history
O Flyway recusa continuar se o checksum calculado não bater com o registrado: qualquer ajuste vira uma migração nova.
Prof. Me. Danilo Bueno [email protected]