Liquibase : outil de gestion de version de BDD

Liquibase

Nous allons aujourd’hui vous présenter Liquibase, une bibliothèque open source (License Apache 2.0) permettant de gérer les changements à appliquer à une base de données. Elle est écrite en Java et fonctionne avec toute base de données qui peut facilement être connectable avec Java (Oracle, MySQL, HSQLDB, etc.).

Cet outil peut servir à la fois pour gérer le versionning de la base de données sur différents environnements, et permettre la gestion des tests d’intégration utilisant un jeu de données.

I. Fonctionnement de Liquibase

Liquibase fonctionne sur des fichiers XML ou des fichiers YAML appelés changeLogs. Ces fichiers changeLogs contiennent un ou plusieurs changeSets, ce qui correspond à une opération sur une base de données qui sera tracée. Voici un exemple du fichier changeLogs :

<?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-3.1.xsd">

	<changeSet id="01" author="sfeir">
		<createTable tableName="Person" remarks="la table contient les informations sur une personne">
			<column name="id" type="int">
				<constraints nullable="false" primaryKey="true" />
			</column>
			<column name="nom" type="varchar(20)">
				<constraints nullable="false" />
			</column>
			<column name="prenom" type="varchar(20)">
				<constraints nullable="false" />
			</column>
			<column name="email" type="varchar(50)">
				<constraints nullable="false" />
			</column>
		</createTable>
	</changeSet>
</databaseChangeLog>

Exemples changeSet (les opérations de base sur la base de données) :

Créer deux tables (Stock et detail_stock) :

	<?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-3.1.xsd">
	
		<changeSet id="01" author="kheireddine.bourahli">
	
			<createTable tableName="STOCK" remarks="A table to contain all the stock">
				<column name="STOCK_ID" type="int">
					<constraints nullable="false" primaryKey="true" />
				</column>
				<column name="STOCK_CODE" type="varchar(10)">
					<constraints nullable="false" />
				</column>
				<column name="STOCK_NAME" type="varchar(20)">
					<constraints nullable="false" />
				</column>
			</createTable>
	
			<createTable tableName="DETAIL_STOCK" remarks="A table to contain all detail stock">
				<column name="DETAIL_STOCK_ID" type="int">
					<constraints nullable="false" unique="true" primaryKey="true" />
				</column>
				<column name="COMP_NAME" type="varchar(100)">
					<constraints nullable="false" unique="true" />
				</column>
	
				<column name="COMP_DESC" type="varchar(255)">
					<constraints nullable="false" unique="true" />
				</column>
	
				<column name="REMARK" type="varchar(255)">
					<constraints nullable="false" unique="true" />
				</column>
				
				<column name="LISTED_DATE" type="Date">
					<constraints nullable="false" />
				</column>
	
				<column name="stock" type="int">
					<constraints nullable="false" />
				</column>
	
			</createTable>
		</changeSet>
	</databaseChangeLog>

Ajouter une contrainte d’intégrité (foreign key) :

	<?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-3.1.xsd">
	
	  <changeSet id="02" author="kheireddine.bourahli">
	    <addForeignKeyConstraint baseTableName="DETAIL_STOCK" baseColumnNames="stock" constraintName="stock_fk" referencedTableName="STOCK" referencedColumnNames="STOCK_ID"/>
	  </changeSet>
	</databaseChangeLog>

Insérer des données dans la table STOCK :

	<?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-3.1.xsd">
	
	  <changeSet id="03" author="Kheireddine.bourahli">
	    <comment>Insert Stocks</comment>
	    <insert tableName="STOCK">
	      <column name="STOCK_ID" valueNumeric="1"/>
	      <column name="STOCK_CODE" value="STK_01"/>
	      <column name="STOCK_NAME" value="stk-name_01"/>
	    </insert>
	    
	    <insert tableName="STOCK">
	      <column name="STOCK_ID" valueNumeric="2"/>
	      <column name="STOCK_CODE" value="STK_02"/>
	      <column name="STOCK_NAME" value="stk-name_02"/>
	    </insert>
	    
	    <insert tableName="STOCK">
	      <column name="STOCK_ID" valueNumeric="3"/>
	      <column name="STOCK_CODE" value="STK_03"/>
	      <column name="STOCK_NAME" value="stk-name_03"/>
	    </insert>
	    
	    <insert tableName="STOCK">
	      <column name="STOCK_ID" valueNumeric="4"/>
	      <column name="STOCK_CODE" value="STK_04"/>
	      <column name="STOCK_NAME" value="stk-name_04"/>
	    </insert>
	    
	    <insert tableName="STOCK">
	      <column name="STOCK_ID" valueNumeric="5"/>
	      <column name="STOCK_CODE" value="STK_05"/>
	      <column name="STOCK_NAME" value="stk-name_05"/>
	    </insert>
	    
	  </changeSet>
	</databaseChangeLog>

Inclure plusieurs fichiers dans un seul fichier ChangeLogs master :

	<?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-3.1.xsd">
	
	  <include file="changelog/01-create-stock-and-detail-stock-schema.xml" relativeToChangelogFile="true"/>
	  <include file="changelog/02-create-constraint-foreign-key.xml" relativeToChangelogFile="true"/>
	  <include file="changelog/03-insert-data-stocks.xml" relativeToChangelogFile="true"/>
	  <include file="changelog/04-insert-data-detail-stock.xml" relativeToChangelogFile="true"/>
	</databaseChangeLog>

Liquibase utilise deux tables (DATABASECHANGELOG, DATABASECHANGELOGLOCK) pour garder la cohérence de la base de données. Ces deux tables seront créées automatiquement dans le schéma de la base de données au premier lancement des opérations de Liquibase :

  • DATABASECHANGELOG : cette table indique à Liquibase quels changeSets ont déjà été exécutés. Liquibase exécute les changeSet dans l’ordre et trace en cas de succès dans cette table le passage du changeSet. Si la table databasechangelog a déjà tracé l’exécution d’un changeSet, Liquibase va ignorer ce changeSet.
  • DATABASECHANGELOGLOCK : cette table permettra à Liquibase d’assurer qu’il n’y a pas deux actions concurrente sur la base de données.

II. Mise en place et utilisation de Liquibase

Liquibase est une bibliothèque conçue pour fonctionner principalement à partir de la ligne de commande, mais elle s’intègre aussi très facilement avec Maven et Spring.

Intégration avec Spring Boot

Ajouter dans le fichier pom.xml la dépendance suivante :

		<dependency>
			<groupId>org.liquibase</groupId>
			<artifactId>liquibase-core</artifactId>
		</dependency>

Configurer le fichier application.properties de Spring Boot :

		```properties
		spring.jpa.hibernate.ddl-auto=none
	
		# enable h2 database 
		spring.h2.console.enabled=true
	
		# database
		spring.datasource.driver-class-name=org.h2.Driver
		spring.datasource.url= jdbc:h2:mem:database-sfeir
		spring.datasource.username=sfeir
		spring.datasource.password=sfeir
	
		# LIQUIBASE
		liquibase.enabled=true
		liquibase.change-log=classpath:db/liquibase-changelog.xml	
	

Ajouter les fichiers changeLogs :

Pour exécuter les opérations de Liquibase, il suffit de lancer la ligne de commande suivante :

		mvn spring-boot:run

Maintenant, on peut accéder à la base de données via cette URL : http://localhost:8080/h2-console

Schéma de la base données :

 

Intégration avec Maven

Ajoutez le plugin de Liquibase dans le fichier pom.xml de Maven :

		<plugin>
			<groupId>org.liquibase</groupId>
			<artifactId>liquibase-maven-plugin</artifactId>
			<version>3.4.2</version>
			<configuration>
				<propertyFile>db/liquibase.properties</propertyFile>
				<changeLogFile>db/liquibase-changelog.xml</changeLogFile>
			</configuration>
		</plugin>

Ce plugin a besoin deux fichiers en entrées :
Liquibase.properties : ce fichier contient les paramètres de connexion de la base de données.
Changelogs.xml : ce fichier contient les opérations de modification de la base de données.

Ajouter les fichiers changelogs et le fichier liquibase.properties dans le répertoire ressources de Maven :

Pour mettre à jour la base de données, il suffit de lancer la ligne de commande suivante :

mvn liquibase:update

Maintenant, on peut vérifier que les opérations changeSet sont bien exécutées sur la base de données :

Intégration avec des lignes de commande :

Vérifier que Java est bien installé sur le poste :

java -version

Téléchargez Liquibase à partir de ce site.

Dézipper le projet Liquibase et exécuter la ligne de commande suivante :

		java -jar liquibase-core.jar 
			--driver= com.mysql.jdbc.Driver  
			--classpath=/path_to/mysql-connector.jar  
			--url=jdbc:mysql://localhost:3306/sfeirdb  
			--username=sfeir  
			--password=****
			--changeLogFile=/path_to/liquibase-changelog.xml update

Conclusion

Liquibase est un outil performant pour maintenir une synchronisation parfaite entre le code et la base de données au sein d’une équipe.

J’ai partagé sur ce lien deux projets de Liquibase (un avec Maven et un avec Spring Boot) et vous pourrez y voir le détail des exemples que j’ai décrit durant cet article.

Vous aimerez aussi...