How do I retrieve auto-generated keys?

package org.kodejava.jdbc;

import java.sql.*;

public class GetGeneratedKeyExample {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        try (Connection connection =
                     DriverManager.getConnection(URL, USERNAME, PASSWORD)) {

            // The orders table have an ID column which value will be auto
            // generated by database. When inserting a new record a new id
            // for the primary key will be generated, and we will get the
            // generated key, so we can use it in another process. For
            // instance if we have a master detail tables where the details
            // table required an id from the master table.
            String sql = """
                    INSERT INTO purchase_order (username, order_date)
                    VALUES ('foobar', '2021-09-25')
                    """;

            Statement stmt = connection.createStatement();

            // When executing the statement we can pass the
            // Statement.RETURN_GENERATED_KEYS so that we can later extract
            // the generated key from the statement object after executing
            // the query.
            stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);

            ResultSet keys = stmt.getGeneratedKeys();
            long lastKey = 1L;
            while (keys.next()) {
                lastKey = keys.getLong(1);
            }

            System.out.println("Last Key: " + lastKey);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The structure of purchase_order table.

CREATE TABLE `purchase_order`
(
    `id`         bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `username`   varchar(50)         NOT NULL,
    `order_date` date                NOT NULL,
    PRIMARY KEY (`id`)
);

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central

How do to commit or rollback transaction in JDBC?

Executing a database manipulation command such as insert, update or delete can sometime throw exception due to invalid data. To protect the integrity of our application data we must make sure that when a transaction fails we must rollback all the executed queries.

In this example we are using MySQL database. To enable transaction capability in MySQL make sure that you are using InnoDB storage engine to create your databases and tables.

package org.kodejava.jdbc;

import java.math.BigDecimal;
import java.sql.*;

public class TransactionRollbackExample {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        try (Connection conn =
                     DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            conn.setAutoCommit(false);

            String orderQuery = """
                    INSERT INTO purchase_order (username, order_date)
                    VALUES (?, ?)
                    """;

            try (PreparedStatement stmt = conn.prepareStatement(orderQuery,
                    PreparedStatement.RETURN_GENERATED_KEYS)) {
                stmt.setString(1, "jduke");
                stmt.setDate(2, new Date(System.currentTimeMillis()));
                stmt.execute();

                ResultSet keys = stmt.getGeneratedKeys();
                long orderId = 1L;
                if (keys.next()) {
                    orderId = keys.getLong(1);
                }

                // This is an invalid statement that will cause exception to
                // demonstrate a rollback.
                String orderDetailQuery = """
                        INSERT INTO purchase_order_detail (order_id, product_id, quantity, price)
                        VALUES (?, ?, ?, ?)
                        """;

                PreparedStatement detailStmt = conn.prepareStatement(orderDetailQuery);
                detailStmt.setLong(1, orderId);
                detailStmt.setInt(2, 1);
                detailStmt.setInt(3, 10);
                detailStmt.setBigDecimal(4, new BigDecimal("29.99"));
                detailStmt.execute();

                // Commit transaction to mark it as a success database operation
                conn.commit();
                System.out.println("Transaction commit...");
            } catch (SQLException e) {
                // Rollback any database transaction due to exception occurred
                conn.rollback();
                System.out.println("Transaction rollback...");
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central

How do I create a connection to MS Access database?

The following example show you how to create a connection to Microsoft Access databases. To allow the database access to be authenticated, the security user account can be added from File -> Info -> Users and Permissions screen.

Just like accessing any other databases in the Java platform we need a JDBC driver. To access Microsoft Access databases we can use UCanAccess, an open-source pure Java JDBC driver for Microsoft Access databases, it allows us to manipulate data in various versions of MS Access databases.

Here what we do in the code snippet below:

  • Prepare USERNAME and PASSWORD that will be used for accessing the database.
  • Define the database JDBC URL which contains the path to MS Access file.
  • Get the connection in try-with-resource statement using the DriverManager.getConnection() method and passes URL, USERNAME, and PASSWORD as arguments.
  • The connection will automatically closed by the try-with-resource when finished.
package org.kodejava.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MSAccessConnect {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";

    private static final String URL =
            "jdbc:ucanaccess://C:/Users/wayan/Temp/kodejava.mdb;";

    public static void main(String[] args) throws Exception {
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Do something with the connection here!
            System.out.println("connection = " + connection);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The connection object printed from the code above:

connection = net.ucanaccess.jdbc.UcanaccessConnection@63376bed[C:\Users\wayan\Temp\kodejava.mdb]

Before JDK 8, the sun.jdbc.odbc.JdbcOdbcDriver driver can be used to connect to Microsoft Access databases. On the example below we can either connect through the DSN created previously on the Windows system, or we can create it in our program as the long URL below.

In Microsoft Access 2003, to allow the database access to be authenticated the security user account can be added from Tools -> Security -> User and Group Accounts menu.

package org.kodejava.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class MSAccessODBCBridge {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";
    private static final String DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";

    // If you want to use you ODBC DSN
    //private static final String URL = "jdbc:odbc:TestDB";
    private static final String URL =
            "jdbc:odbc:Driver={MICROSOFT ACCESS DRIVER (*.mdb, *.accdb)};" +
            "DBQ=C:/Users/wayan/Temp/kodejava.mdb;";

    public static void main(String[] args) throws Exception {
        Class.forName(DRIVER);
        try (Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
            // Do something with the connection here!
            System.out.println("connection = " + connection);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The connection object printed from the code above:

connection = sun.jdbc.odbc.JdbcOdbcConnection@4ec4f498

Maven Dependencies

<dependency>
  <groupId>io.github.spannm</groupId>
  <artifactId>ucanaccess</artifactId>
  <version>5.1.1</version>
</dependency>

How do I disable auto-commit mode in JDBC?

The code snippet below shows you how to disable auto-commit operation when executing JDBC commands or queries.

package org.kodejava.jdbc;

import java.sql.*;

public class AutoCommitSettingExample {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        // DO: Get a connection to database, we need to obtain the
        // database connection prior to executing any JDBC commands
        try (Connection connection =
                     DriverManager.getConnection(URL, USERNAME, PASSWORD)) {

            // Disable the auto-commit operation. By default, every statement
            // executed against database in JDBC is in auto-commit mode. To
            // disable auto-commit set it to false
            connection.setAutoCommit(false);

            // DO: Execute some other database operation here
            String sql = "DELETE FROM book WHERE id = ?";
            try (PreparedStatement statement = connection.prepareStatement(sql)) {
                statement.setLong(1, 1L);
                statement.executeUpdate();

                // Finally we must call the commit method explicitly to finish
                // all database manipulation operation
                connection.commit();
            } catch (SQLException e) {
                // When some exception occurs rollback the transaction.
                connection.rollback();
                throw e;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central