Contactez-nous

Intégration de Liquibase avec Spring Boot

Découvrez comment utiliser Liquibase avec Spring Boot pour une gestion avancée des migrations de schéma de base de données via des changelogs structurés (XML, YAML, JSON, SQL).

Liquibase : Une approche structurée de la migration

Tout comme Flyway, Liquibase est un outil open-source de premier plan dédié à la gestion des migrations de schéma de base de données. Il permet de suivre, versionner et appliquer les changements de manière fiable et automatisée à travers différents environnements. L'objectif principal est d'assurer la cohérence du schéma de la base de données avec le code applicatif qui l'utilise.

L'approche de Liquibase diffère légèrement de celle de Flyway. Au lieu de se baser principalement sur des scripts SQL versionnés, Liquibase utilise des fichiers changelog, le plus souvent écrits en XML, YAML ou JSON (bien qu'il supporte aussi le SQL formaté). Ces changelogs décrivent les changements de manière plus abstraite (par exemple, "créer une table", "ajouter une colonne"), permettant potentiellement une meilleure portabilité entre différentes bases de données (Liquibase génère le SQL approprié pour la base cible).

Spring Boot offre une intégration transparente avec Liquibase, permettant d'exécuter automatiquement les migrations nécessaires au démarrage de l'application.

Ajouter la dépendance Liquibase

Pour intégrer Liquibase, commencez par ajouter la dépendance liquibase-core à votre projet. Comme pour Flyway, Spring Boot gère généralement la version via son BOM.

Avec Maven (pom.xml) :


    org.liquibase
    liquibase-core





Avec Gradle (build.gradle) :

implementation 'org.liquibase:liquibase-core'

// Assurez-vous d'avoir aussi une dépendance pour l'accès aux données
// (ex: implementation 'org.springframework.boot:spring-boot-starter-data-jpa')
// et le driver JDBC (ex: runtimeOnly 'org.postgresql:postgresql')

Une DataSource configurée dans votre application (via les propriétés `spring.datasource.*`) est également requise pour que Liquibase puisse se connecter à la base de données.

Auto-configuration et fonctionnement par défaut

Si liquibase-core est détecté sur le classpath et qu'une DataSource est disponible, Spring Boot auto-configure et exécute Liquibase au démarrage de l'application, avant l'initialisation de JPA/Hibernate.

Le processus par défaut est le suivant :

  1. Spring Boot crée une instance de liquibase.integration.spring.SpringLiquibase.
  2. Liquibase recherche un fichier changelog principal dans un emplacement par défaut sur le classpath.
  3. Il se connecte à la base de données et vérifie l'état des migrations en consultant ses tables de métadonnées (par défaut `DATABASECHANGELOG` et `DATABASECHANGELOGLOCK`).
  4. Il identifie et applique tous les `changeSet` (unités de changement) définis dans le changelog qui n'ont pas encore été exécutés.

Par défaut, Spring Boot recherche le fichier changelog principal à l'emplacement classpath:db/changelog/db.changelog-master.yaml ou classpath:db/changelog/db.changelog-master.xml (ou .json, .sql). Vous devez donc généralement créer le dossier src/main/resources/db/changelog/ et y placer votre fichier changelog maître.

Format des 'changelogs' Liquibase (XML, YAML, JSON, SQL)

Le fichier changelog est le coeur de Liquibase. Il contient une liste de changeSet, où chaque changeSet représente une unité atomique de changement de schéma.

Chaque changeSet doit avoir un attribut id et un attribut author uniques (la combinaison id + author doit être unique à travers tous les changelogs). Liquibase utilise ces identifiants pour savoir quels changeSets ont déjà été appliqués.

A l'intérieur d'un changeSet, vous décrivez les changements en utilisant les balises/clés fournies par Liquibase (ex: createTable, addColumn, addForeignKeyConstraint) ou en incluant directement du SQL (via la balise ou équivalent).

Exemple (YAML - `src/main/resources/db/changelog/db.changelog-master.yaml`) :

databaseChangeLog:
  - changeSet:
      id: 1
      author: app_dev
      changes:
        - createTable:
            tableName: app_user
            columns:
              - column:
                  name: id
                  type: BIGINT
                  autoIncrement: true # Ou gérer via sequence
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: username
                  type: VARCHAR(100)
                  constraints:
                    unique: true
                    nullable: false
              - column:
                  name: email
                  type: VARCHAR(150)
                  constraints:
                    unique: true
  - changeSet:
      id: 2
      author: app_dev
      changes:
        - addColumn:
            tableName: app_user
            columns:
              - column:
                  name: registration_date
                  type: TIMESTAMP
  - changeSet:
      id: 3 # Exemple avec du SQL direct
      author: dba
      changes:
       - sql:
           sql: INSERT INTO app_user (username, email) VALUES ('admin', 'admin@example.com'); 
           # Attention à l'idempotence si nécessaire
  # Inclure d'autres fichiers changelog
  # - include:
  #     file: db/changelog/changes/changelog-v1.1.yaml

Exemple (XML - `src/main/resources/db/changelog/db.changelog-master.xml`) :




    
        
            
                
            
            
                
            
            
                
            
        
    

    
        
            
        
    
    
    
    


L'utilisation de formats comme XML ou YAML permet à Liquibase de générer le SQL spécifique à la base de données cible, offrant une meilleure portabilité que les scripts SQL purs.

Configuration via `application.properties`/`yml`

De nombreuses options de configuration sont disponibles pour adapter le comportement de Liquibase :

# application.properties

# Activer/Désactiver Liquibase (défaut: true si liquibase-core est présent)
spring.liquibase.enabled=true

# Chemin vers le fichier changelog maître (défaut: classpath:/db/changelog/db.changelog-master.yaml ou .xml)
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-main.xml

# Contexte(s) à exécuter (permet d'exécuter des changeSets spécifiques, ex: pour tests)
# spring.liquibase.contexts=test,dev

# Label(s) à exécuter (autre mécanisme de filtrage)
# spring.liquibase.labels=v1.0

# Nom de la table de log (défaut: DATABASECHANGELOG)
# spring.liquibase.database-change-log-table=my_changelog

# Nom de la table de verrou (défaut: DATABASECHANGELOGLOCK)
# spring.liquibase.database-change-log-lock-table=my_changelog_lock

# Schéma par défaut où exécuter Liquibase
# spring.liquibase.default-schema=public

# Drop les objets de la BDD au démarrage avant migration (TRES DANGEREUX, pour tests uniquement)
# spring.liquibase.drop-first=false

# Exécuter une mise à jour "à vide" pour marquer les changeSets comme exécutés sans les appliquer
# spring.liquibase.test-rollback-on-update=false

Les contextes (`contexts`) et les labels (`labels`) sont des fonctionnalités puissantes de Liquibase pour exécuter sélectivement des `changeSet` en fonction de l'environnement ou d'autres critères.

Coordination avec JPA/Hibernate

Comme pour Flyway, il est essentiel de coordonner Liquibase avec JPA/Hibernate pour éviter les conflits de gestion de schéma. La recommandation est la même :

# application.properties
spring.jpa.hibernate.ddl-auto=validate # ou none

Utilisez validate pour que Hibernate vérifie la cohérence entre le schéma (géré par Liquibase) et vos entités au démarrage, ou none pour désactiver toute action de Hibernate sur le schéma (option la plus sûre en production). Evitez absolument create, create-drop, et update lorsque Liquibase est actif.

Liquibase vs Flyway : Lequel choisir ?

Le choix entre Liquibase et Flyway dépend souvent des préférences de l'équipe et des besoins spécifiques :

  • Flyway : Préféré si vous êtes à l'aise avec l'écriture directe de SQL et que vous voulez une approche simple basée sur des scripts SQL versionnés.
  • Liquibase : Préféré si vous souhaitez décrire les changements de manière plus abstraite (XML/YAML/JSON), si la portabilité entre différentes bases de données est un critère important, ou si vous avez besoin de fonctionnalités avancées comme les contextes, les labels, les preConditions ou les rollbacks automatiques (Liquibase peut générer des instructions de rollback pour certains types de changements).

Les deux outils sont excellents et bien intégrés à Spring Boot.

Conclusion : Une gestion structurée et fiable du schéma

Liquibase, intégré à Spring Boot, fournit une solution puissante et flexible pour automatiser et versionner les migrations de votre schéma de base de données. En utilisant des fichiers changelog structurés, il permet une gestion fiable des évolutions de la base, assure la cohérence entre les environnements et facilite le travail collaboratif. Son approche abstraite des changements peut également offrir une meilleure portabilité et des fonctionnalités avancées par rapport aux scripts SQL purs.