Saturday, August 2, 2008

Liquibase + Maven

In IT today, our processes are too often manual (i.e., slow and costly) which limits change and, in part, forces us to model a dynamic business with a database designed for the business as it was years ago. By incorporating a versioned database build along with the regular application build, developers can be in control of the application environment rather than slaves to past design decisions no longer make sense.

Here I've documented a Maven build that includes execution of a database modification using Liquibase. Liquibase is a database model management tool that integrates with your build tool such that database changes are managed along with application code. Implementing and rolling back modifications and refactorings affecting application code and the database occur easily and simultaneously. With Liquibase, changes to the database can be diffed and merged along side application code. Liquibase integrates easily with Hibernate to automatically create the database updates required by changes to your Hibernate classes. Use Maven and Liquibase; fear change no more.

The pom.xml file was created using the default archetype (fig. 1) then edited to include the MySQL and Liquibase dependencies and the Liquibase build element(fig. 2). The Liquibase changelog file (src/main/resources/changelog.xml) is from the Liquibase Quickstart example (fig.3). Finally, there are the commands to start MySQL, create the database and run Maven (fig. 4).

C:\src\java\liquibase_project>mvn archetype:create -DgroupId=com.mouse.app 
-DartifactId=mouseapp -DarchetypeArtifactId=maven-archetype-webapp
 
 

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mouse.app</groupId>
  <artifactId>mouseapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>mouseapp Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>3.1.14</version>
    </dependency>
    <dependency>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-core</artifactId>
      <version>1.7.0</version>
    </dependency>
    <dependency>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-plugin</artifactId>
      <version>1.7.0.0</version>
    </dependency>
  </dependencies>
    
  <build>
    <finalName>mouseapp</finalName>
    <plugins>
       <plugin>
         <groupId>org.liquibase</groupId>
         <artifactId>liquibase-plugin</artifactId>
         <version>1.6.1.0</version>
         <executions>
           <execution>
             <phase>process-resources</phase>
             <configuration>
               <changeLogFile>src/main/resources/changelog.xml</changeLogFile>
               <driver>com.mysql.jdbc.Driver</driver>
               <url>jdbc:mysql://localhost:3306/mousedb</url>
               <username>root</username>
               <password>root</password>
             </configuration>
             <goals>
               <goal>update</goal>
             </goals>
           </execution>
         </executions>
      </plugin>
    </plugins>
  </build>
</project>
 
 

<?xml version="1.0" encoding="UTF-8"?>

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

    <changeSet id="1" author="bob" dbms="mysql">
      <createTable tableName="department">
         <column name="id" type="int">
             <constraints primaryKey="true" nullable="false"/>
         </column>
         <column name="name" type="varchar(50)">
             <constraints nullable="false"/>
         </column>
         <column name="active" type="boolean" defaultValue="1"/>
      </createTable>
    </changeSet>
 
</databaseChangeLog>
 
 

C:\src\java\liquibase_project\mouseapp>mysql -u root -p
 
Enter password: ****
 
mysql> create database mousedb;
 
mysql> quit
 
C:\src\java\liquibase_project\mouseapp>mvn clean package