Liquibase – zarządzanie zmianą w bazie danych


Liquibase – zarządzanie zmianą w bazie danych

Rozwój aplikacji niesie za sobą konieczność aktualizacji bazy danych. Dostarczanie odpowiednich skryptów które mają za zadanie zaktualizować bazę danych nie jest dobrym rozwiązaniem ponieważ w momencie wystąpienia błędu nie jesteśmy w stanie w prosty sposób stwierdzić które zmiany zostały wprowadzone a które nie. Z pomocą przychodzi liquibase. Rozwiązanie to napisane w Javie pozwala zarządzać zmianami w bazie danych. Narzędzie liquibase  jest często integrowane z narzędziami budowania aplikacji np. Apache Maven.

Tworzymy nowy projekt spring-boot oparty o Mavena – plik pom.xml:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>com.h2database</groupId>
		<artifactId>h2</artifactId>
		<version>1.4.199</version>
	</dependency>
</dependencies>
 
<build>
	<plugins>
		<plugin>
			<groupId>org.liquibase</groupId>
			<artifactId>liquibase-maven-plugin</artifactId>
			<version>2.0.1</version>
			<configuration>
				<changeLogFile>src/main/resources/db-changelog.xml</changeLogFile>
				<propertyFile>src/main/resources/jdbc.properties</propertyFile>
			</configuration>
			<executions>
				<execution>
					<goals>
						<goal>clearCheckSums</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
 
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

Klasa startowa:

@SpringBootApplication
public class LiquibaseApplication {
	public static void main(String[] args) {
		SpringApplication.run(LiquibaseApplication.class, args);
	}
}

Plik application.properties:

spring.datasource.url             = jdbc:h2:file:./Database;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE
spring.datasource.driverClassName = org.h2.Driver
spring.datasource.username        = sa
spring.datasource.password        = password
spring.jpa.database-platform      = org.hibernate.dialect.H2Dialect
 
spring.h2.console.enabled         = true
spring.h2.console.path            = /h2-console

Plik jdbc/src/main/resources/db-changelog.xml:

<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-2.0.xsd">
 
    <changeSet id="schema" author="pl.javaleader">
 
        <createTable tableName="users">
            <column autoIncrement="true" name="id" type="bigserial">
                <constraints nullable="false" primaryKey="true" primaryKeyName="id"/>
            </column>
            <column name="login" type="VARCHAR(200)">
                <constraints nullable="false" unique="true"/>
            </column>
            <column name="password" type="VARCHAR(200)">
                <constraints nullable="false"/>
            </column>
            <column name="role" type="VARCHAR(300)"/>
        </createTable>
        <rollback>
            <dropTable tableName="users"/>
        </rollback>
    </changeSet>
 
</databaseChangeLog>

Plik src/main/resources/jdbc.properties:

driver   = org.h2.Driver
url      = jdbc:h2:file:./Database;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE
username = sa
password = password

W bazie danych H2 tworzone są dwie tabele – databasechangelog oraz databasechangeloglock. W tabeli databasechangelog znajdują wpisy które opisują wszystkie zmiany jakie zostały już wgrane do bazy danych, tak aby zostały one wykonane tylko raz. Tabela databasechangeloglock wykorzystywana celem uniknięcia problemów w momencie kiedy kilka klientów próbuje zaktualizować bazę danych.

Wykonujemy polecenie aktualizacji bazy danych:

mvn liquibase:update

Wynik:

[INFO] Executing on Database: jdbc:h2:file:./Database;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE
INFO 17.07.19 14:00:liquibase: Successfully acquired change log lock
INFO 17.07.19 14:00:liquibase: Creating database history table with name: DATABASECHANGELOG
INFO 17.07.19 14:00:liquibase: Reading from DATABASECHANGELOG
INFO 17.07.19 14:00:liquibase: Reading from DATABASECHANGELOG
INFO 17.07.19 14:00:liquibase: ChangeSet src/main/resources/db-changelog.xml::schema::pl.javaleader ran successfully in 6ms
INFO 17.07.19 14:00:liquibase: Successfully released change log lock
INFO 17.07.19 14:00:liquibase: Successfully released change log lock

Jeśli coś pójdzie nie tak, należy użyć polecenia czyszczącego sumy kontrolne:

mvn liquibase:clearCheckSums

Wynik:

[INFO] Executing on Database: jdbc:h2:file:./Database;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE
INFO 17.07.19 14:01:liquibase: Clearing database change log checksums
INFO 17.07.19 14:01:liquibase: Successfully acquired change log lock
INFO 17.07.19 14:01:liquibase: Successfully released change log lock
INFO 17.07.19 14:01:liquibase: Successfully released change log lock


Leave a comment

Your email address will not be published.


*