This is a mobile version, full one is here.
Yegor Bugayenko
20 July 2014
Liquibase with Maven
Liquibase is a migration management tool for relational databases. It versionalizes schema and data changes in a database; similar to the way Git or SVN works for source code. Thanks to their Maven plugin, Liquibase can be used as a part of a build automation scenario.
Maven Plugin
Let’s assume you’re using MySQL (PostgreSQL or any other database configuration will be very similar.)
Add liquibase-maven-plugin
to your pom.xml
(get its latest
version in Maven Central):
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<configuration>
<changeLogFile>
${basedir}/src/main/liquibase/master.xml
</changeLogFile>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://${mysql.host}:${mysql.port}/${mysql.db}</url>
<username>${mysql.login}</username>
<password>${mysql.password}</password>
</configuration>
</plugin>
</plugins>
</build>
</project>
To check that it works, run mvn liquibase:help
.
I would recommend you keep database credentials
in settings.xml
and in their respective profiles. For example:
<settings>
<profiles>
<profile>
<id>production</id>
<properties>
<mysql.host>db.example.com</mysql.host>
<mysql.port>3306</mysql.port>
<mysql.db>example</mysql.db>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<mysql.host>test-db.example.com</mysql.host>
<mysql.port>3306</mysql.port>
<mysql.db>example-db</mysql.db>
</properties>
</profile>
</profiles>
</settings>
When you run Maven, don’t forget to turn
on one of the profiles. For example: mvn -Pproduction
.
Initial Schema
I assume you already have a database with a schema (tables, triggers, views, etc.) and some data. You should “reverse engineer” it and create an initial schema file for Liquibase. In other words, we should inform Liquibase where we are at the moment, so that it starts to apply changes from this point.
Maven plugin doesn’t support it, so you will have to run
Liquibase directly. But, it’s not that difficult. First,
run mvn liquibase:help
in order to download all artifacts.
Then, replace placeholders with your actual credentials:
$ java -jar \
~/.m2/repository/org/liquibase/liquibase-core/3.1.1/liquibase-core-3.1.1.jar \
--driver=com.mysql.jdbc.Driver \
--url=jdbc:mysql://db.example.com:3306/example \
--username=example --password=example \
generateChangeLog > src/main/liquibase/2014/000-initial-schema.xml
Liquibase will analyze your current database schema
and copy its own schema into src/main/liquibase/2014/000-initial-schema.xml
.
Master Changeset
Now, create XML master changeset and save it to src/main/liquibase/master.xml
:
<databaseChangeLog
xmlns="https://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<includeAll path="src/main/liquibase/2014" />
</databaseChangeLog>
It is an entry point for Liquibase. It starts from this file
and loads all other changesets available in src/main/liquibase/2014
.
They should be either .xml
or .sql
. I recommend that you use
XML mostly because it is easier to maintain and works faster.
Incremental Changesets
Let’s create a simple changeset, which adds a new column to an existing table:
<databaseChangeLog xmlns='https://www.liquibase.org/xml/ns/dbchangelog'
xmlns:xsi='https://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='https://www.liquibase.org/xml/ns/dbchangelog
https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd'>
<changeSet id="002" author="Yegor">
<sql>
ALTER TABLE user ADD COLUMN address VARCHAR(1024);
</sql>
</changeSet>
</databaseChangeLog>
We save this file in src/main/liquibase/2014/002-add-user-address.xml
.
In big projects, you can name your files by the names of the tickets
they are produced in. For example, 045-3432.xml
, which means changeset
number 45 coming from ticket #3432.
The important thing is to have this numeric prefix in front of file names, in order to sort them correctly. We want changes to be applied in their correct chronological order.
That’s it. We’re ready to run mvn liquibase:update -Pproduction
and
our production database will be updated—a new column will be
added to the user
table.
Also, see how MySQL Maven Plugin can help you to automate integration testing of database-connected classes.