{"id":5041,"date":"2017-02-01T03:12:02","date_gmt":"2017-02-01T08:12:02","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=5041"},"modified":"2018-09-25T03:46:28","modified_gmt":"2018-09-25T07:46:28","slug":"mysql-and-liquibase","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/mysql-and-liquibase\/","title":{"rendered":"MySQL and Liquibase"},"content":{"rendered":"<p>This post introduces you to <a href=\"http:\/\/www.liquibase.org\/\">Liquibase<\/a> &#8211; a database changeset management tool. I will cover its installation, usage and execution with MySQL.<\/p>\n<hr \/>\n<p><strong>WHAT IS LIQUIBASE?<\/strong><\/p>\n<p>Liquibase is an open source library to track database changes. Liquibase supports XML, JSON, and YAML files. This post uses XML files to make certain concepts clear. When Liquibase runs, there are several commands it can execute. The most important one is the UPDATE command, which applies database changes from a file. Generally, every application development is built around a concept of a linear database version which starts at version 1. After a change is added, the version is incremented to 2, then 3, etc. This works well for projects where only a single person adds the changesets and there is only one branch. The approach fails when different developers add different versions to the database concurrently. Liquibase provides a solution to this issue by using a unique identification scheme for each changeset that is designed to guarantee uniqueness across developers.<\/p>\n<p><strong>WHAT ARE CHANGESETS<\/strong><\/p>\n<p>Changesets are units of work for Liquibase to apply. It is basically the SQL you want to apply to the database. Each changeset should be a single, independent unit of work. You should never have one changeset applying multiple changes unless it is absolutely necessary. Changelogs are how you tell Liquibase what changesets to apply and in what order. The order in which the changesets appear in the changelog is the order in which they will be executed.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Liquid_base.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-5372 aligncenter\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Liquid_base-300x145.png\" alt=\"liquid_base\" width=\"304\" height=\"147\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Liquid_base-300x145.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Liquid_base.png 600w\" sizes=\"auto, (max-width: 304px) 100vw, 304px\" \/><\/a><\/p>\n<p><strong>LIQUIBASE SPECIFIC TABLES<\/strong><\/p>\n<p>The first time you run Liquibase it creates two tables in the database: DATABASECHANGELOG and DATABASECHANGELOGLOCK. The lock table is used to prevent concurrent Liquibase runs from stepping on each other. DATABASECHANGELOG is used to keep track of what changesets have been applied to a database. The initial run will obviously be against an empty table, so all changesets will be applied. Liquibase uses a combination of <strong>id\/author\/filepath<\/strong> to create a changeset id.<\/p>\n<hr \/>\n<p><strong>Installation requirements:<\/strong><\/p>\n<p>Liquibase 3.x requires Java. So let&#8217;s get installed first and other pre-requisites for executing Liquibase using command line options and a <a href=\"https:\/\/maven.apache.org\/plugins\/\">Maven<\/a> Plugin.<\/p>\n<ul>\n<li>Install JDK from this location &#8211; <a href=\"http:\/\/www.oracle.com\/technetwork\/java\/javase\/downloads\/index.html\">Install JDK<\/a><\/li>\n<li>Add the location of the bin folder of the JDK installation for the Path variable in System Variables. The following is a typical value for the path variable: &#8220;C:\\Program Files\\Java\\jdk1.7.0\\bin&#8221;<\/li>\n<li>Install the Mysql Connector for Java from <a href=\"http:\/\/www.mysql.com\/products\/connector\/\">JDBC Driver for MySQL (Connector\/J)<\/a><\/li>\n<li>To install Liquibase, download the compressed Liquibase Core file from <a href=\"http:\/\/www.liquibase.org\/download\">http:\/\/www.liquibase.org\/download<\/a> to a local directory.The extracted files contain a liquibase.bat and Liquibase shell script for Windows and Mac\/UNIX systems.<\/li>\n<li>Add the directory containing the liquibase.bat file to your system&#8217;s PATH.<\/li>\n<li>Test the installation by opening a command prompt and entering the following command:<br \/>\n<em>Liquibase &#8211;version<\/em><br \/>\nThe result should be something like: Liquibase Version: 3.5.3<\/li>\n<\/ul>\n<p>Liquibase can be executed in various ways depending on your requirement, depends on what works best for you.There are three main ways to run Liquibase:<\/p>\n<p><strong>Automatically on startup<\/strong> &#8211; This method works best in environments where you have less control over the deployment process or if you want a simpler deployment process. You can set Liquibase to run automatically on startup using built in Spring or Servlet Listener support or interacting with a simple Java API.<br \/>\n<strong>Manual deployment<\/strong> &#8211; You can execute Liquibase manually in command line application, or can be run on Ant or Maven. In this post, I will show how to execute using the command line and Maven Plugin. These interfaces allow you to execute Liquibase commands whenever you need, without being tied to application startup.<br \/>\n<strong>Executing SQL<\/strong> &#8211; For those who need to know exactly what is being done to their database, Liquibase supports an \u201cupdateSQL\u201d mode from the command line, Ant or Maven interfaces.<\/p>\n<p>Now that you understood how Liquibase works and about its installation, let&#8217;s get started with its execution. For better understanding I have broadly divided into four steps:<\/p>\n<ul>\n<li>Create a database <em>change log<\/em><\/li>\n<li>Create a <em>change set <\/em>inside the change log file.<\/li>\n<li>Run the change set against a database via the command line<\/li>\n<li>Verify the change in the database.<\/li>\n<\/ul>\n<p>R<strong>unning liquibase using command line interface<\/strong> &#8211; For demonstration purposes I\u2019ve created a database named &#8216;liquibasetraining&#8217; on my local MySQL server, as well as a changelog file (db.changelog-1.0.xml). You can keep it in your project folder or in a separate location, but changelog files should be under version control as shown below.<\/p>\n<p>Here\u2019s the first version of our changelog file with no changesets.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/Basic-changelog.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5098\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/Basic-changelog-300x69.png\" alt=\"basic-changelog\" width=\"569\" height=\"131\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/Basic-changelog-300x69.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/Basic-changelog.png 673w\" sizes=\"auto, (max-width: 569px) 100vw, 569px\" \/><\/a><br \/>\nOn the command-line navigate to the location where you are keeping the changelog file and run the following command:<\/p>\n<pre lang=\"python\">liquibase \r\n--driver=com.mysql.jdbc.Driver \r\n--classpath=c:\/mysql-connector-java-5.1.21-bin.jar \r\n--changeLogFile=db.changelog-1.0.xml \r\n--url=\"jdbc:mysql:\/\/localhost:3306\/liquibasetraining?autoReconnect=true&amp;useSSL=false\" \r\n--username=root\r\n--password=password123\r\nupdate<\/pre>\n<p>In the above command, all of the parameters except classpath are required. Driver specifies the class name of the database driver that we want to use. changeLogFile is the name of our database changelog. URL specifies the JDBC database connection string which includes the server type, hostname and database name. classpath is where you keep the classes, like the database connector, used by Liquibase.<\/p>\n<p>When Liquibase connects to the database using the given username and password, it should create two tables in the application database, DATABASECHANGELOG and DATABASECHANGELOGLOCK (as shown below). Each row represents a change made to the database. It contains useful details like id, author, filename, timestamp and tag information.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Basic-changelog2.png\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5340\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Basic-changelog2.png\" alt=\"basic-changelog2\" width=\"223\" height=\"115\" \/><\/a><\/p>\n<p>Instead of specifying command line parameters each time you run Liquibase, you can keep them in a Java properties file named liquibase.properties in the same directory. Then you can just run liquibase &lt;command&gt;.The properties file would look like this. Here we are using master.xml which has the changelog file db.changelog-1.0.xml.<\/p>\n<pre lang=\"python\">changeLogFile=C:\\liquibase\\master.xml\r\ndriver=com.mysql.jdbc.Driver\r\nurl=jdbc:mysql:\/\/localhost:3306\/liquibasetraining?autoReconnect=true&amp;useSSL=false\r\nusername=root\r\npassword=password123<\/pre>\n<p>Next let\u2019s create a user table order with id, Ordername and Qty fields by adding a changeset to db.changelog-1.0.xml. In this below example tag element means it applies a tag to the database for future rollback. Here\u2019s the updated XML:<\/p>\n<pre lang=\"xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<databaseChangeLog\r\n    xmlns=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\"\r\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\r\n        http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/dbchangelog-3.1.xsd\">  \r\n    <changeSet id=\"1\" author=\"indira\">\r\n        <createTable tableName=\"order\">\r\n            <column name=\"id\" type=\"int\">\r\n                <constraints primaryKey=\"true\" nullable=\"false\"\/>\r\n            <\/column> \r\n            <column name=\"Ordername\" type=\"varchar(50)\"\/>\r\n            <column name=\"Qty\" type=\"int\">\r\n                <!--<constraints nullable=\"false\"\/>-->\r\n            <\/column>\r\n        <\/createTable>\r\n    <\/changeSet>\r\n\t<changeSet id=\"tag-1.0\" author=\"indira\">\r\n\t    <tagDatabase tag=\"1.0\" \/>\r\n\t<\/changeSet>     \r\n<\/databaseChangeLog>\r\n<\/pre>\n<p>Now run Liquibase using below command (using liquibase.properties file) and look at the result<\/p>\n<pre lang=\"python\">liquibase\r\n--defaultsFile=c:\\liquibase\\liquibase.properties\r\n--classpath=c:\\mysql-connector-java-5.1.40-bin.jar\r\nupdate<\/pre>\n<p>If you look at the database , you&#8217;ll see the following structure:<\/p>\n<p><strong><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/order2_jan2.png\" data-rel=\"lightbox-image-3\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5334\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/order2_jan2-300x130.png\" alt=\"order2_jan2\" width=\"319\" height=\"138\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/order2_jan2-300x130.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/order2_jan2.png 332w\" sizes=\"auto, (max-width: 319px) 100vw, 319px\" \/><\/a><\/strong><\/p>\n<p><strong>Running Liquibase using Maven<\/strong>: Till now I showed you how to use command line commands with and without the liquibase.properties file. If the command line interface does not fit your needs, Liquibase can be run on Maven or Ant. Liquibase can be controlled via a Maven plug-in which can be obtained from the central Maven repository. It gives advantages like the control over dependencies, running tests, plugins, versioning your software, etc.<\/p>\n<p><strong>Prerequisites for using Maven Plugin:<\/strong><\/p>\n<ul>\n<li>Install Maven Plugin from: <a href=\"http:\/\/maven.apache.org\/\">Maven repository<\/a>.<\/li>\n<li>Add the bin directory of the created directory apache-maven-3.3.9 to the PATH environment variable. For more details on installation use this <a href=\"http:\/\/maven.apache.org\/install.html\">link<\/a><\/li>\n<li>Confirm with mvn &#8211;version<\/li>\n<\/ul>\n<p><strong>For Running Liquibase using Maven:<\/strong><\/p>\n<p>1. <strong>Create a Project<\/strong> &#8211; You need a directory for your project to reside, for this we need to execute the following Maven command on your command line :<\/p>\n<pre lang=\"python\">mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -archetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false<\/pre>\n<p>Running the archetype plugin will create a skeleton Maven project in the directory <strong>my-app<\/strong> along with a POM.xml.<\/p>\n<p>2. <strong>Add the Liquibase Plugin to your POM<\/strong> &#8211; The pom.xml file is the core of a project&#8217;s configuration in Maven. It is a single configuration file that contains the majority of information required to build a project in just the way you want. The POM structure is a bit complex, but it is not necessary to understand all of the tags but understanding important tags is enough to use it effectively. Once the POM.xml is generated, we will need to add the dependencies the database project relies on. For us, it&#8217;s the MySQL JDBC driver and off course Liquibase itself.<br \/>\nConfiguration of the plugin is done via the Plugin section of the pom.xml, So i have added the Liquibase Maven Plugin in the section. Below is my POM.xml<\/p>\n<pre lang=\"xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" \r\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">\r\n\t<modelVersion>4.0.0<\/modelVersion>\r\n  \t<groupId>se.nrm.mediaserver<\/groupId>\r\n        <artifactId>db<\/artifactId>\r\n        <version>1.0-SNAPSHOT<\/version>\r\n        <packaging>jar<\/packaging>\r\n        <name>Liquibase-maven-test<\/name>\r\n \t<dependencies>\r\n          <dependency>\r\n             <groupId>org.liquibase<\/groupId>\r\n             <artifactId>liquibase-core<\/artifactId>\r\n             <version>3.5.3<\/version>\r\n          <\/dependency>\r\n          <dependency>\r\n             <groupId>mysql<\/groupId>\r\n             <artifactId>mysql-connector-java<\/artifactId>\r\n             <version>5.1.37<\/version>\r\n         <\/dependency>\r\n\t <\/dependencies>\r\n    \t<build>\r\n\t   <plugins>\r\n\t     <plugin>\r\n                <groupId>org.liquibase<\/groupId>\r\n                <artifactId>liquibase-maven-plugin<\/artifactId>\r\n                <version>3.5.3<\/version>\r\n\t\t<configuration>\r\n\t\t   <propertyFile>C:\\my-app\\src\\main\\resources\\liquibase\\liquibase.properties<\/propertyFile>\r\n\t\t<\/configuration>\r\n                <executions>\r\n\t\t   <execution>\r\n                      <goals>\r\n\t\t         <goal>update<\/goal>\r\n                      <\/goals>\r\n     \t\t   <\/execution>\r\n                <\/executions>\r\n             <\/plugin>\r\n           <\/plugins>\r\n         <\/build>\r\n<\/project>\r\n<\/pre>\n<p>This is going to add the Liquibase Maven plugin to your project and point your build at a properties file for configuration.<\/p>\n<p><strong>Create a Liquibase Properties File<\/strong> : The property file should contain the following details<\/p>\n<pre lang=\"python\">changeLogFile=C:\/my-app\/src\/main\/resources\/liquibase\/master_1.0.xml\r\ndriver=com.mysql.jdbc.Driver\r\nurl=jdbc:mysql:\/\/localhost:3306\/mavenblogproject?autoReconnect=true&amp;useSSL=false\r\nusername=root\r\npassword=password123<\/pre>\n<p>The best practice is always using a master_1.0.xml file as an entry file. In this master_1.0.xml file, there&#8217;s no logic defined, only a set of includes. In our example i have created two change log files db-changelog-1.1.xml(create tables) and db-changelog-1.2.xml(insert tables) as shown below<br \/>\nmaster_1.0.xml<\/p>\n<pre lang=\"xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n<databaseChangeLog \r\n  xmlns=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/1.9\" \r\n  xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" \r\n  xsi:schemaLocation=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/1.9\r\n                      http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/dbchangelog-1.9.xsd\"> \r\n    <include file=\"C:\\my-app\\src\\main\\resources\\liquibase\\db-changelog-1.1.xml\"\/>\r\n    <include file=\"C:\\my-app\\src\\main\\resources\\liquibase\\db-changelog-1.2.xml\"\/>\r\n<\/databaseChangeLog> \r\n<\/pre>\n<p>db-changelog-1.1.xml<\/p>\n<pre lang=\"xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<databaseChangeLog\r\n    xmlns=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\"\r\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\r\n         http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/dbchangelog-3.1.xsd\">\r\n\t\t <changeSet id=\"1\" author=\"indira\">\r\n\t\t\t<createTable tableName=\"clinicallab\">\r\n\t\t\t\t<column name=\"id\" type=\"int\"\r\n\t\t\t\tautoIncrement=\"true\">\r\n\t\t\t\t<constraints primaryKey=\"true\" nullable=\"false\"\/>\r\n\t\t\t\t<\/column>\r\n\t\t\t\t<column name=\"labname\" type=\"varchar(50)\"\/>\r\n\t\t\t\t<column name=\"lablocation\" type=\"varchar(50)\">\r\n\t\t\t\t<constraints nullable=\"false\"\/>\r\n\t\t\t\t<\/column>\r\n\t\t\t<\/createTable>\r\n\t\t\t<\/changeSet>\r\n\t\t\t<changeSet id=\"2\" author=\"indira\">\r\n\t\t\t<createTable tableName=\"Department\">\r\n\t\t\t\t<column name=\"deptid\" type=\"int\"\r\n\t\t\t\tautoIncrement=\"true\">\r\n\t\t\t\t<constraints primaryKey=\"true\" nullable=\"false\"\/>\r\n\t\t\t\t<\/column>\r\n\t\t\t\t<column name=\"deptname\" type=\"varchar(50)\"\/>\r\n\t\t\t\t<column name=\"deptlocation\" type=\"varchar(50)\">\r\n\t\t\t\t<constraints nullable=\"false\"\/>\r\n\t\t\t\t<\/column>\r\n\t\t\t<\/createTable>\r\n\t\t\t<\/changeSet>\r\n\t\t\t<changeSet id=\"tag-1.1\" author=\"indira\">\r\n\t\t\t\t<tagDatabase tag=\"1.1\" \/>\r\n\t\t\t<\/changeSet>\r\n<\/databaseChangeLog>\r\n<\/pre>\n<p>db-changelog-1.2.xml<\/p>\n<pre lang=\"xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<databaseChangeLog\r\n    xmlns=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\"\r\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\r\n         http:\/\/www.liquibase.org\/xml\/ns\/dbchangelog\/dbchangelog-3.1.xsd\">\r\n\t\t<changeSet id=\"2-insert\" author=\"indira\">\r\n\t\t\t<insert tableName=\"department\">\r\n\t\t\t\t<column name=\"deptid\" value=\"01\"\/>\r\n\t\t\t\t<column name=\"deptname\" value=\"sales\"\/>\r\n\t\t\t\t<column name=\"deptlocation\" value=\"India\"\/>\r\n\t\t\t<\/insert>\r\n\t\t<\/changeSet>\r\n\t\t<changeSet id=\"tag-1.2\" author=\"indira\">\r\n\t\t\t<tagDatabase tag=\"1.2insert\" \/>\r\n\t\t<\/changeSet>\r\n<\/databaseChangeLog>\r\n<\/pre>\n<p>Now, you can execute liquibase using Maven command. From the my-app directory execute below command<\/p>\n<pre>mvn liquibase:update<\/pre>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/maven_success.png\" data-rel=\"lightbox-image-4\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-5322\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2016\/12\/maven_success-300x169.png\" alt=\"maven_success\" width=\"400\" height=\"169\" \/><\/a><\/p>\n<p>Now check the database, in the databasechangelog table, all changesets are executed. New tables are created and data is populated in the schema mavenblogproject (as shown below)<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Result-changelogtable_last.png\" data-rel=\"lightbox-image-5\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5347\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Result-changelogtable_last-300x68.png\" alt=\"result-changelogtable_last\" width=\"503\" height=\"114\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Result-changelogtable_last-300x68.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Result-changelogtable_last-768x175.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2017\/01\/Result-changelogtable_last.png 860w\" sizes=\"auto, (max-width: 503px) 100vw, 503px\" \/><\/a><\/p>\n<p>This post covered parts of Liquibase functionality. After reading this, you should be able to:<\/p>\n<ul>\n<li>Understand how Liquibase works<\/li>\n<li>How to apply change log to a database<\/li>\n<li>How to execute Liquibase using command line<\/li>\n<li>How to execute Liquibase using Maven Plugin<\/li>\n<\/ul>\n<p>Beyond tracking and applying changes to a database, Liquibase supports many other powerful commands for rolling back changes, generating SQL instead of applying changes and generating documentation. If you want to undo an update, liquibase.bat rollback allows you to roll back changesets based on the number of changesets, to a given date, or to a given tag stored in the database.<\/p>\n<p><strong>If you are a startup finding it hard to hire technical QA engineers, learn more <a href=\"https:\/\/qxf2.com\/blog\/about-qxf2\/\">about Qxf2 Services<\/a>.<\/strong><\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>This post introduces you to Liquibase &#8211; a database changeset management tool. I will cover its installation, usage and execution with MySQL. WHAT IS LIQUIBASE? Liquibase is an open source library to track database changes. Liquibase supports XML, JSON, and YAML files. This post uses XML files to make certain concepts clear. When Liquibase runs, there are several commands it [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[129,127],"tags":[],"class_list":["post-5041","post","type-post","status-publish","format-standard","hentry","category-liquibase","category-mysql"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/5041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=5041"}],"version-history":[{"count":92,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/5041\/revisions"}],"predecessor-version":[{"id":9820,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/5041\/revisions\/9820"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=5041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=5041"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=5041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}