Simple DB Migration with JDBC

During my recent move away from wordpress to get CodeBlahger up and running I was faced with a number of technical challenges, not the least of which being how in the world I was going to take several years of posts stored in a MariaDB instance using the wordpress schemea, and move them over to the MySQL instance running in a docker container with the CodeBlahger schemea. In preparation for the migration I had decide what language I would use to automate the process - I wasnt about to do this by hand - and how integrated into the CodeBlahger platform i wanted to make the migration process. After weighing the pros and cons of using python or perl I scrapped both ideas and ultimately decided to stick Java for writing the code to handle the migration. As for integrating that code into CodeBlahger, I decided against it and implemented a standalone app. Migrating the data would (hopefully) only occur once, it didnt make sense to me to clutter up the code base with support for such a limited use feature. 

In todays post I am going to outline the steps taken to move content from one database instance to another using JDBC in Java 17, so lets get to it.

Configuring the Database Connections

Connecting to a database with Java is straight forward, with the only complication being the need for a "driver" for the specific vendor of database your project is using. This can be handled automatically with a build tool like maven or Gradle, or you can download the jar files from the db vendors website and place them in your classpath. However you choose to do this, it is necessary so dont try to skip it.

JDBC is configured with a string containing the name of the type of db were connecting to, the hostname, port, and database. You will also need the login credentials of the db your connecting to.
import java.sql.*;
import java.time.*;

public class DBMigration {
    private static final String OLD_DB_URL = "jdbc:mariadb://localhost:3306/wordpress";
    private static final String OLD_DB_USER = "oldusername";
    private static final String OLD_DB_PASSWORD = "oldpassword";

    private static final String NEW_DB_URL = "jdbc:mysql://localhost:3307/blahgdb";
    private static final String NEW_DB_USER = "newusername";
    private static final String NEW_DB_PASSWORD = "newpassword";
The Connection and DriverManager classes are both in Java.sql and made accessible through those files i said you needed in your class path earlier. Our connection is established by providing the url, user, and password strings we configured above to the getConnection() method of DriverManger. At this point, a connection with the database is either established or an exception will be thrown.
public static void doMigration() {
        Connection oldDbConnection = null;
        Connection newDbConnection = null;
        ResultSet resultSet = null;
        try {
            oldDbConnection = DriverManager.getConnection(OLD_DB_URL, OLD_DB_USER, OLD_DB_PASSWORD);
            newDbConnection = DriverManager.getConnection(NEW_DB_URL, NEW_DB_USER, NEW_DB_PASSWORD);

Querying The Database

Assuming that we have successfully established both connections, we can start pulling our post data from our old database and inserting it into the new scheme. Queries are written as strings and then supplied to the PreparedStatement class for execution by the db driver. If our statement was properly formatted, we will be returned a ResultSet, which is an iterable collection of the data we requested. On failure, an exception is thrown. That ResultSet is an iterable collectgion is very convenient, as when it comes time to insert that data into the new database, we can easily loop over each entry to add it to the new schema.
            String selectSQL = "SELECT id, post_title, post_content, post_date FROM wp_posts WHERE post_status = 'publish'";            
            PreparedStatement selectStatement = oldDbConnection.prepareStatement(selectSQL);
            resultSet = selectStatement.executeQuery();

            String insertSQL = "INSERT INTO posts (title, content, created_at, user_id, category_id) VALUES (?, ?, ?, 1, 1)";
            PreparedStatement insertStatement = newDbConnection.prepareStatement(insertSQL);
Take notice of the '?'s in the INSERT query, these are template markers which we can address by index and populate using the data from the result set, updating the statements contents and executing for every entry. This has the net result of moving the content from the old database to the new database without the need for any kind of custom dto classes.
     while (resultSet.next()) {
                // Fetch data from the old database
                String title = resultSet.getString("post_title");
                String content = "<p>" + resultSet.getString("post_content") + "</p>";
		        Date created = resultSet.getDate("post_date");
                
                //populate insert statement with fetched data
                insertStatement.setString(1, title);
                insertStatement.setString(2, content);
                insertStatement.setDate(3, created);

                // Execute insert into new database
                insertStatement.executeUpdate();
          }
          System.out.println("Data migration completed successfully.");

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // Close connections
            try {
                if (resultSet != null) resultSet.close();
                if (oldDbConnection != null) oldDbConnection.close();
                if (newDbConnection != null) newDbConnection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

Granted, it was a little more complicated than that, but honestly not by much. At anypoint if an exception is raised, we catch the exception and print the stack trace to see where may have goofed, otherwise we clean up whatever resources/connections were aquired and the migration is done. I'm still doing alot of work getting the new design up and running, but wanted to post something new. That's all i've got for now, so until next time Happy Hacking!


Leave A Comment