Database Migrations in Java: Overview of Popular Tools

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Database Migrations in Java: Why You Need Them and How They Work



Developing any serious application in Java is inextricably linked to the evolution of the database schema. Adding new fields, changing data types, creating indexes — all of this is inevitable as a project develops. Manually executing SQL scripts in different environments (local development environment, test bench, production) quickly leads to chaos: scripts get lost, are executed in the wrong order, and one team's database differs from another's. The solution to this problem is database migrations.



Migrations allow you to version schema changes, automatically apply them in the correct sequence, and roll them back if necessary. In the Java world, there are two undisputed leaders in this area: Flyway and Liquibase. Let's take a closer look at them.



Flyway: Simplicity and Reliability



Flyway is a lightweight, simple, and powerful migration tool. Its philosophy is: "Migrations are just SQL or Java classes." The main operating principles are:



  • Versioning: each migration file has a unique version number (e.g., V1__create_users.sql, V2__add_email.sql).
  • Execution order: Flyway tracks applied migrations in a special table (flyway_schema_history) and only applies new ones.
  • Two types of migrations: SQL scripts and Java migrations (for complex logic).
  • Rollback: supports "undo" migrations (in the paid version) or manual writing of rollback scripts.


Example of working with Flyway



Suppose you need to create a users table. You create a file db/migration/V1__create_users.sql:



CREATE TABLE users (    id BIGINT AUTO_INCREMENT PRIMARY KEY,    username VARCHAR(50) NOT NULL,    email VARCHAR(100) NOT NULL,    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);


Then you add a second migration V2__add_age.sql:



ALTER TABLE users ADD COLUMN age INT;


Connecting Flyway to a Spring Boot application is done via application.properties:



spring.flyway.enabled=truespring.flyway.locations=classpath:db/migrationspring.datasource.url=jdbc:postgresql://localhost:5432/mydbspring.datasource.username=userspring.datasource.password=pass


When the application starts, Flyway will check the history table and apply all new migrations. If a migration has already been executed, it will be skipped.



Liquibase: Flexibility and Control



Liquibase is a more flexible and powerful tool that supports several formats for describing changes: XML, YAML, JSON, and SQL. Its key feature is changesets.



  • Unique identifier: each changeset has an id and an author.
  • Automatic SQL generation: Liquibase can generate SQL for a specific DBMS (PostgreSQL, MySQL, Oracle, etc.).
  • Contexts: you can separate migrations for different environments (dev, test, prod).
  • Rollback: each changeset can have a rollback instruction (rollback).


Example of working with Liquibase



Example of a changeset in XML format (db/changelog/db.changelog-master.xml):



<?xml version="1.0" encoding="UTF-8"?><databaseChangeLog    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog    http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<changeSet id="1" author="pythonlib"> <

Recommendations