Motivação

Atualmente, existem vários frameworks para criar e gerenciar um banco de dados relacional com Java. Com o Hibernate, por exemplo, é possível criar e alterar tabelas sem precisar escrever uma linha de script SQL. Entretanto, dependendo do escopo do projeto, às vezes é necessário que essas alterações sejam controladas mais de perto. Um sistema crítico, por exemplo, pode precisar de certas otimizações em tabelas para melhorar sua performance. Para esses casos ou onde também há uma equipe dedicada para gerenciar os bancos de dados, o Liquibase pode se mostrar uma boa opção para ajudar no controle e execução dos scripts SQL.

Passo 1: Configuração

Para utilizar o Liquibase em seu projeto Java, basta configurá-lo em sua ferramenta de gerenciamento de projetos. No exemplo apresentado nesse artigo, utilizaremos o Maven. Além disso, também faremos uso do MySQL.

Sabendo disso, na seção build do arquivo pom.xml, adicione o plugin liquibase-maven-plugin colocando as informações de acesso ao banco, como mostra a Listagem 1.


<plugin>
 <groupId>org.liquibase</groupId>
 <artifactId>liquibase-maven-plugin</artifactId>
 <version>3.1.0</version>
 <configuration>
     <changeLogFile>src/main/resources/db-scripts/db.changelog.xml</changeLogFile>
     <driver>com.mysql.jdbc.Driver</driver>
 </configuration>
 <executions>
     <execution>
         <id>liquibase-install</id>
         <phase>install</phase>
         <goals>
             <goal>update</goal>
         </goals>
         <configuration>
             <url>jdbc:mysql://mysql.devmedia.com.br/artigo</url>
                 <username>root</username>
                 <password></password>				
         </configuration>
     </execution>
 </executions>
 <dependencies>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>5.0.4</version>
     </dependency>
 </dependencies>
</plugin>	
Listagem 1. Declarando o plugin do Liquibase no pom.xml.

Na linha 6 dessa listagem informamos o local do arquivo de controle dos changeLogs que iremos criar. Um changeLog é um arquivo que possui um conjunto de changeSets e cada um desses representa um conjunto de comandos que o Liquibase deverá executar na base.

O arquivo db.changelog.xml é mostrado na Listagem 2. Nesse arquivo é definido o tipo do banco de dados que será utilizado (no nosso caso, o MySQL) e o nome da pasta onde os arquivos de changeLog estarão. Para facilitar na organização dos scripts, iremos agrupá-los em subpastas com os nome das versões que serão geradas do código.


<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"	xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog   
 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
 http://www.liquibase.org/xml/ns/dbchangelog-ext   
 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

	<preConditions>
		<dbms type="mysql" />
	</preConditions>
	<includeAll path="src/main/resources/db-scripts/scripts/1.0.0/"/>
</databaseChangeLog>
Listagem 2. Conteúdo do arquivo db.changelog.xml.

Passo 2: Criando os scripts SQL

Dentro da pasta configurada na Listagem 2 criaremos um arquivo com os comandos SQL propriamente ditos. Uma sugestão é utilizar uma nomenclatura que contenha o número do changeLog (no exemplo, o número é 01) e a data em que ele foi criado (15-11-2016). Manter esse padrão é importante porque o Liquibase executará todos os arquivos contidos nessa pasta, seguindo pelo nome em ordem alfabética.


--liquibase formatted sql

--changeset rafael:1

DROP TABLE IF EXISTS `product`;
CREATE TABLE  `product` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `description` varchar(200) NOT NULL,
  `price` double(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8;
  
--rollback drop table `product`;

--changeset rafael:2
INSERT INTO `product` VALUES  (1,'Celular','Motorola G4',900);

-- rollback delete from `product` where id = 1;
Listagem 3. Conteúdo do arquivo db.changelog-01-15-11-2016.sql

A Listagem 3 apresenta o script do nosso primeiro changeLog. Observe que os comandos SQL estão agrupados em changeSets. Por definição, a primeira linha do arquivo deve conter um comentário com o texto liquibase formatted sql. Já o início de um changeSet deve possuir uma linha de comentário com a palavra changeSet. Para especificar o fim do conjunto de comandos, o Liquibase entende o “;” (ponto e vírgula) da última instrução SQL do changeSet ou uma linha de comentário com a palavra rollback e um comando SQL que reverte a ação executada pelo comando do changeSet. Além disso, cada changeSet deve ter um identificador, normalmente especificado com o nome da pessoa que criou o comando e um número sequencial.

Passo 3: Executando o Liquibase

Depois de configurar o plugin e criar os arquivos com os scripts, precisamos apenas executar o comando do Maven para fazer o Liquibase rodar os scripts SQL na base de dados. Na linha 12 da Listagem 1, configuramos o plugin para ser executado na fase de install do Maven. Assim, toda vez que o comando de install iniciar, ele também executará o Liquibase:


mvn install -Dliquibase.dropFirst=true

O argumento liquibase.dropFirst=true indica ao Liquibase que ele deve apagar todo o banco e executar todos os scripts SQL novamente. Se esse argumento não for informado, ou for igual a false, o Liquibase executará apenas os scripts que ainda não foram executados, pois ele controla os changeSets que já foram executados em uma tabela própria. Outra opção para fazer o Liquibase rodar os scripts do banco é executar o comando update do próprio plugin, como demonstrado a seguir:


mvn liquibase:update -Dliquibase.dropFirst=true

Finalmente, se você precisar voltar o banco de dados para uma determinada versão, o comando rollback do Liquibase poderá ser utilizado. Por exemplo, se você quiser que o comando do último changeSet executado seja desfeito, basta executar:


mvn liquibase:rollback -Dliquibase.rollbackCount=1

Nesse comando informamos ao Liquibase que ele deve realizar o rollback dos comandos de 1 changeSet, contando a partir do último que foi aplicado ao banco.

Utilizando esses comandos e seguindo a estrutura sugerida para os arquivos de changeLog, podemos gerenciar a estrutura do banco de dados de forma bastante simples ao longo do projeto, evitando a necessidade de recorrer a um software específico para executar scripts, como phpMyAdmin, Workbench ou pgAdmin.