Aller au contenu
  1. Articles/

Ecrire une migration Liquibase en Java

·2 mins·

Article publié il y a 11 ans : les outils et les commandes décrits ont pu changer depuis.

Liquibase est un outil très utile pour versionner sa base de données. La succession de refactoring à appliquer à une base peut-être décrite dans plusieurs formats de données (XML, YAML, JSON et SQL). Seulement il arrive qu’une migration soit “trop” complexe pour être décrite à partir des refactoring standards (ou alors tout simplement que l’on ne soit pas très à l’aise avec PL/SQL).
Dans ce cas on peut écrire un changement particulier en Java.

Implémenter un CustomChange
#

Liquibase propose deux interfaces pour créer son refactoring personnel, CustomTaskChange et CustomSqlChange. La première permet d’appliquer des changements qui ne génèrent pas de SQL contrairement à la seconde.
Cette dernière est à privilégier quand c’est possible puisque cela permet de sauvegarder le SQL généré dans un fichier (via un dryRun par exemple).

public class MyCustomChangeThatGenerateSql implements CustomSqlChange {

    @Override
    public SqlStatement[] generateStatements(final Database database) throws CustomChangeException {

        List<SqlStatement> statements = new ArrayList<>();
        
        JdbcConnection connection = (JdbcConnection) database.getConnection();
        try {
            ResultSet persons = connection.createStatement().executeQuery("select nom, prenom from person");
            while (persons.next()) {
                // Write your complex logic in here !
                // and generate SqlStatement(s)
            }
        } catch (DatabaseException | SQLException e) {
            throw new CustomChangeException(e);
        }
        
        SqlStatement insert = new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "person")
            .addColumnValue("nom", "Gay")
            .addColumnValue("prenom", "Jean-Christophe");
            
        SqlStatement update = new UpdateStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "person")
            .addNewColumnValue("prenom", "Jc")
            .setWhereClause(String.format("nom='%s'", Gay))
        
        statements.add(insert);
        statements.add(update);
            
        return statements.toArray(new SqlStatement[statements.size()]);
    }
    
    @Override
    public String getConfirmationMessage() {
        return null;
    }

    @Override
    public void setUp() throws SetupException {}

    @Override
    public void setFileOpener(ResourceAccessor resourceAccessor) {}

    @Override
    public ValidationErrors validate(Database database) {
        return null;
    }
}

La principale logique se passe dans la méthode generateStatements. L’API de Liquibase nous donne accès à la connexion Jdbc et il suffit de générer des SqlStatement pour décrire son refactoring.
Le reste des méthodes à implémenter permet de valider la configuration, accéder à des fichiers, etc. La Javadoc explique tout ça.

Configurer son changeset
#

L’élément customChange permet de déclarer la classe implémentant le refactoring.

<changeSet id="20140606-super-complex-change" author="jc.gay">
    <customChange class="fr.jcgay.MyCustomChangeThatGenerateSql" />
</changeSet>

Et voilà on peut décrire des changements complexes dans son langage préféré !

Partager

Articles connexes

A la découverte de Java 8

·21 mins
Java 8 est maintenant disponible depuis plusieurs semaines, voici un “petit” résumé des fonctionalités de Java 8 que j’ai testé à travers tous les articles sur lesquels je suis tombé.