Migrations for Java EVOLUINDO SEU BANCO DE MANEIRA INCREMENTAL Rafael Ponte QCon SP 2013 EM 2005 EU SÓ QUERIA SABER DE FRAMEWORKS ANALISTA DE SISTEMAS NA EQUIPE I ♥ HIBERNATE I ♥ HIBERNATE persistence.xml <?xml version="1.0" encoding="UTF-­‐8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-­‐unit name="IssueTracker"> <properties> <!-- ... --> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-­‐unit> </persistence> Nova Entidade @Entity class Issue { @Id private Long id; private String descricao; … } INFO [SchemaUpdate ] Running hbm2ddl schema update INFO [SchemaUpdate ] fetching database metadata INFO [SchemaUpdate ] updating schema ... INFO [TableMetadata] table not found: issue INFO [SchemaUpdate ] create table issue (id bigserial not null, descricao varchar(255)) ... INFO [SchemaUpdate ] schema update complete I ♥ HIBERNATE Entidade ATUALIZADA! @Entity class Issue { @Id private Long id; private String descricao; private String status = "A"; … } INFO [SchemaUpdate ] Running hbm2ddl schema update INFO [SchemaUpdate ] fetching database metadata INFO [SchemaUpdate ] updating schema ... INFO [TableMetadata] table found: issue INFO [TableMetadata] columns: [id, descricao] INFO [SchemaUpdate ] alter table issue add column status varchar(255) ... INFO [SchemaUpdate ] schema update complete I ♥ HIBERNATE Entidade ATUALIZADA! <3 @Entity class Issue { @Id private Long id; @Column(length=1000) private String descricao; private String status = "A"; … } EM PRODUÇÃO java.sql.SQLException: Data truncated for column 'descricao' at row 1 INFO [SchemaUpdate ] Running hbm2ddl schema update INFO [SchemaUpdate ] fetching database metadata INFO [SchemaUpdate ] updating schema ... INFO [TableMetadata] table found: issue INFO [TableMetadata] columns: [id, status, descricao] INFO [TableMetadata] foreign keys: [] INFO [TableMetadata] indexes: [issue_pkey] ??????????? #WTF ... INFO [SchemaUpdate ] schema update complete ϟ I ♥ HIBERNATE SEMPRE PODE PIORAR SEMPRE PODE PIORAR MUDE O NOME DA COLUNA SEMPRE PODE PIORAR MUDE O TIPO DA COLUNA SEMPRE PODE PIORAR ADICIONE UMA COLUNA NOT-NULL “ WARNING: We've seen Hibernate users trying to use SchemaUpdate to update the schema of a production database automatically. This can quickly end in disaster and won't be allowed by your DBA. -- Java Persistence with Hibernate “ WARNING: We've seen Rafael Ponte trying to use SchemaUpdate to update the schema of a production database automatically. This can quickly end in disaster and won't be allowed by your DBA. -- Java Persistence with Hibernate ϟ I ♥ HIBERNATE APRENDI: GERAR SCHEMA COM HIBERNATE SOMENTE NO INICIO DO PROJETO CORRIGINDO O BANCO NA MÃO Não tá entrando na tela... CORRIGINDO O BANCO NA MÃO Mario Diniz Não tá entrando na tela... CORRIGINDO O BANCO NA MÃO E o meu banco? Handerson Frota Mario Diniz ALGO ESTAVA ERRADO, EVOLUIR O BANCO ERA CARO Migrations for Java EVOLUINDO SEU BANCO DE MANEIRA INCREMENTAL @rponte Príncipe do Oceano Fortaleza - Terra do Sol Como você evolui sua APP? Como você evolui seu BANCO? gerencia mudanças Como você evolui seu BANCO? PREPARA UM HUGE_SCRIPT.SQL E APLICA MANUALMENTE? DEIXA NA MÃO DO DBA? DEIXA NA MÃO DO * ARQUITETO? * BDUF (Big Design Up Front) NÓS ♥ TECN OLO GIA CAS CRIA SUA PRÓPRIA FERRAMENTA, CERTO? EIRA OU GERA COM HIBERNATE? Não importa qual solução você utilize... CADA SOLUÇÃO TEM VANTAGENS E DESVANTAGENS CADA SOLUÇÃO TEM SEUS PRÓS E CONTRAS A COMUNIDADE RUBYONRAILS APRENDEU DESDE O COMEÇO SIMPLES E EFICAZ: MIGRATIONS A COMUNIDADE JAVA PARECE QUE NÃO APRENDEU AINDA COMO SE FAZ Java ferramentas para todos os gostos TODAS SEGUEM O MESMO CONCEITO RESUMINDO EM 4 PASSOS 1 CRIE O SCRIPT COM A MUDANÇA script.sql CREATE TABLE 'blog' ( 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 'descricao' VARCHAR(255) NOT NULL PRIMARY KEY ('id') ) 1 CRIE O SCRIPT COM A MUDANÇA create_table_blog.sql CREATE TABLE 'blog' ( 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 'descricao' VARCHAR(255) NOT NULL PRIMARY KEY ('id') ) 1 CRIE O SCRIPT COM A MUDANÇA 1_create_table_blog.sql CREATE TABLE 'blog' ( 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 'descricao' VARCHAR(255) NOT NULL PRIMARY KEY ('id') ) 1 CRIE O SCRIPT COM A MUDANÇA <ID>_<DESCRIPTION>.sql CREATE TABLE 'blog' ( 'id' INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 'descricao' VARCHAR(255) NOT NULL PRIMARY KEY ('id') ) 2 APLICA O SCRIPT NO BANCO [rponte] ~/myblog/scripts $ migrate up 2 APLICA O SCRIPT NO BANCO [rponte] ~/myblog/scripts $ migrate up -­‐env=PRODUCTION -­‐env=HOMOLOG -­‐env=DEV -­‐env=TEST 3 VERSIONA A MUDANÇA NO BANCO mysql> select * from DB_VERSION; +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ | ID | DESCRIPTION | +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ | 1 | create table blog | +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ 4 APLICA SCRIPTS AINDA NÃO APLICADOS [rponte] ~/myblog/scripts $ migrate up mysql> select * from DB_VERSION; +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ | ID | DESCRIPTION | +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ | 1 | create table blog | | 2 | create table author | | 3 | create table post | +-­‐-­‐-­‐-­‐+-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐+ 1 CRIA O SCRIPT 2 APLICA SCRIPT 3 VERSIONA O BANCO 4 APLICA NOVOS SCRIPTS Java ferramentas para todos os gostos Java ferramentas para todos os gostos flyway mybatis liquibase MYBATIS FLYWAY LIQUIBASE MIGRATIONS MYBATIS FLYWAY LIQUIBASE MIGRATIONS Flyway Flyway > Plain SQL migrations > Java migrations > Convention over Configuration > SQL Parser > Java API - Ant - Maven - Gradle MYBATIS FLYWAY LIQUIBASE MIGRATIONS Liquibase Liquibase > XML migrations > Plain SQL migrations > Multiple Databases > Rollback support > Generation of SQL scripts for DBA MYBATIS FLYWAY LIQUIBASE MIGRATIONS MyBatis Schema Migrations MyBatis Schema Migrations > Plain SQL migrations > Maven > Rollback support > Generation of SQL scripts for DBA APESAR DE TANTAS OPÇÕES HOJE EM DIA APESAR DE TANTAS OPÇÕES HOJE EM DIA EM 2009 ERA DIFERENTE APESAR DE TANTAS ADOTAMOS O OPÇÕES HOJE MYBATIS EM DIA MIGRATIONS WINDOWS, ADOTAMOS O LINUX E MACOSX MYBATIS MIGRATIONS PODEMOS FACILITAR E FOI O QUE FIZEMOS ANT SCRIPT Mybatis-Migrations-Anttasks github.com/rponte/mybatis-migrations-anttasks PODEMOS FACILITAR E FOI O QUE MARCELO FEZ GRADLE PLUGIN Ant é tão OLD! PODEMOS FACILITAR E FOI O QUE MARCELO FEZ GRADLE PLUGIN Gradle-Migrations-Plugin github.com/marceloemanoel/gradle-migrations-plugin MyBatis Migrations MAVEN MyBatis Migrations MAVEN ANT MyBatis Migrations MAVEN ANT GRADLE FLYWAY LIQUIBASE MYBATIS MIGRATIONS FLYWAY LIQUIBASE MYBATIS MIGRATIONS QUAL ESCOLHER? MIGRATIONS MIGRATIONS EVOLUÇÃO = SUSTENTÁVEL DO BANCO EVOLUÇÃO MELHOR MIGRATIONS + PROCESSO = SUSTENTÁVEL DO BANCO MELHORE O PROCESSO EQUIPE RESPONSÁVEL PELO BANCO COLOQUE AS MIGRATIONS NO CONTROLE DE VERSÃO - BANCO DE DADOS COMPARTILHADO - NAO USE EM DESENVOLVIMENTO Rafael Mario Handerson Banco de Dados ...... Rafael Mario Handerson ...... Banco Banco Banco ...... Rafael Mario Handerson ...... Schema Schema Schema ...... Banco de Dados AUTOMATIZE O MÁXIMO QUE PUDER Rafael Rafael v48 v48 Rafael Mario v48 v49 Rafael Handerson v48 v43 deploy frequente Rafael Rafael v48 v48 Rafael Mario v48 v49 Rafael Handerson v48 v43 Integration v48 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 Q&A v44 Integration v48 Demo v45 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v44 Produção v43 Integration v48 Demo v45 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v44 Produção v43 Integration v48 Demo v45 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v44 Produção v43 Integration v49 Demo v45 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v49 Produção v43 Integration v49 Demo v45 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v49 Produção v43 Integration v49 Demo v49 Rafael Handerson v48 v43 deploy frequente deploy controlado Rafael Rafael v48 v48 Rafael Mario v48 v49 deploy MUITO controlado Q&A v49 Produção v49 Integration v49 Demo v49 Rafael Handerson v48 v43 NÃO MODIFIQUE MIGRATIONS QUE FORAM PARA PRODUÇÃO GRANDES MUDANÇAS PEQUENAS MIGRATIONS EVOLUÇÃO MELHOR MIGRATIONS + PROCESSO = SUSTENTÁVEL DO BANCO SEMPRE PODE PIORAR APP BANCO APP APPS que você APPS que APPS quevocê você conhece conhece conhece Frameworks de persistência APPS que você NÃO APPS que você APPS que vocêNÃO NÃO conhece conhece conhece BANCO Outros Outros bancos bancos Data Data exporters exporters Data Data importers importers Código de teste APP APPS que você APPS que APPS quevocê você conhece conhece conhece APPS que você NÃO APPS que você APPS que vocêNÃO NÃO conhece conhece conhece “Deus no céu, e Banco de dados na terra.” Frameworks de persistência BANCO Outros Outros bancos bancos Data Data exporters exporters Data Data importers importers Código de teste EVOLUIR O BANCO NESSE CENÁRIO É CARO Aplica as migrations, migra os dados, escreve código de compatibilidade Transição Resultado { { { Original Remove schema antigo e código de compatibilidade modifica o banco período de transição (antigo e novo) finaliza a modificação CONCLUINDO EVOLUIR O BANCO É MAIS DIFÍCIL DO QUE A APLICAÇAO TRABALHE JUNTAMENTE COM O DBA ESTUDE, EXPERIMENTE E ESCOLHA UMA MIGRATIONS TOOL Rafael Ponte [email protected]