Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java code changeset in liquibase

Is there a way in liquibase to create java code change set (i.e. provide a java class, which will receive a JDBC connection and will perform some changes in the database) ?

(I know that flyway has such feature)

like image 452
Pavel Bernshtam Avatar asked Aug 16 '12 12:08

Pavel Bernshtam


People also ask

How do I create a changeset in Liquibase?

Running the generate-changelog command Instead of using a properties file, you can pass the necessary information from the command line. Note: If you want to create an SQL changelog file, add your database type name when specifying the changelog file: liquibase --changelog-file=mychangelog.

What is a changeset in Liquibase?

The changeset tag is a unit of change that Liquibase executes on a database and which is used to group database Liquibase Change Types together. A list of changes created by multiple changesets are tracked in a changelog.

How do I run a .SQL file in Liquibase?

Running the execute-sql command To run the execute-sql command, specify the following parameters in the Liquibase properties file, environment variables, or the command prompt while running the command: URL, driver [optional], and user authentication information such as username and password.

What is Liquibase in Java?

Liquibase offers a powerful open source database migration tool for Java apps. It brings structure and confidence to developers and DBAs that need to easily create and track database schema changes.


Video Answer


2 Answers

Yes, there is such feature. You can create a customChange:

    <customChange class="my.java.Class">         <param name="id" value="2" />     </customChange> 

The class must implements the liquibase.change.custom.CustomTaskChange interface.

@Override public void execute(final Database arg0) throws CustomChangeException {     JdbcConnection dbConn = (JdbcConnection) arg0.getConnection();     try {          ... do funny stuff ...     } catch (Exception e) {         // swallow the exception !     } } 
like image 80
poussma Avatar answered Oct 06 '22 00:10

poussma


A complete example will look like this

Create a class that implements CustomTaskChange or CustomSqlChange.

package com.example;  import liquibase.change.custom.CustomTaskChange; import liquibase.database.Database; import liquibase.database.jvm.JdbcConnection; import liquibase.exception.CustomChangeException; import liquibase.exception.SetupException; import liquibase.exception.ValidationErrors; import liquibase.logging.LogFactory; import liquibase.resource.ResourceAccessor;  import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.PreparedStatement; import java.sql.ResultSet;  public class DataLoaderTask implements CustomTaskChange {      //to hold the parameter value     private String file;       private ResourceAccessor resourceAccessor;       public String getFile() {         return file;     }      public void setFile(String file) {         this.file = file;     }       @Override     public void execute(Database database) throws CustomChangeException {         JdbcConnection databaseConnection = (JdbcConnection) database.getConnection();         try {              //Opening my data file             BufferedReader in = new BufferedReader(                     new InputStreamReader(resourceAccessor.getResourceAsStream(file)));              //Ignore header             String str = in.readLine();              while ((str = in.readLine()) != null && !str.trim().equals("")) {                 LogFactory.getLogger().info("Processing line "+ str);                 //Do whatever is necessary             }             in.close();         } catch (Exception e) {             throw new CustomChangeException(e);         }     }      @Override     public String getConfirmationMessage() {         return null;     }      @Override     public void setUp() throws SetupException {      }      @Override     public void setFileOpener(ResourceAccessor resourceAccessor) {         this.resourceAccessor = resourceAccessor;     }      @Override     public ValidationErrors validate(Database database) {         return null;     }  } 

In the changeset xml you could use the class as below

<changeSet id="1" author="murali" runAlways="false" failOnError="true" >         <customChange class="com.example.DataLoaderTask">             <param name="file" value="/com/example/data/user.csv" />         </customChange> </changeSet> 

For me the data file is in src/main/resources/com/example/data directory

Hope this helps

like image 38
Murali Avatar answered Oct 05 '22 23:10

Murali