How do I use the BiConsumer functional interface in Java?

The BiConsumer interface in Java is part of the java.util.function package and is used when we need to perform an operation that takes two input arguments and does not return any result. It is a functional interface commonly used in lambda expressions or functional programming scenarios.

Key Features:

  1. It accepts two arguments of potentially different types.
  2. It does not return a result (void return type).
  3. It is primarily used for side effect operations (e.g., printing, modifying objects, etc.).

Method in BiConsumer:

  • void accept(T t, U u): Performs this operation on the given arguments.
  • Additionally, it has a default method:
    • default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after): Returns a composed BiConsumer that performs the operation of this BiConsumer first, followed by the after operation.

Example Usage:

Basic Example with Lambda

package org.kodejava.util.function;

import java.util.function.BiConsumer;

public class BiConsumerExample {
  public static void main(String[] args) {
    // Create a BiConsumer that adds two numbers and prints the result
    BiConsumer<Integer, Integer> addAndPrint =
            (a, b) -> System.out.println("Sum: " + (a + b));

    // Use the BiConsumer
    addAndPrint.accept(10, 20); // Output: Sum: 30
  }
}

Using BiConsumer to Manipulate a Map

The BiConsumer is often used with collections such as Map.

package org.kodejava.util.function;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

public class BiConsumerWithMap {
  public static void main(String[] args) {
    // Map of items
    Map<String, Integer> items = new HashMap<>();
    items.put("Apples", 10);
    items.put("Oranges", 20);
    items.put("Bananas", 30);

    // Define a BiConsumer to print key-value pairs
    BiConsumer<String, Integer> printEntry =
            (key, value) -> System.out.println(key + ": " + value);

    // Iterate through each entry in the map
    items.forEach(printEntry);
  }
}

Output:

Apples: 10
Bananas: 30
Oranges: 20

Combining BiConsumers with andThen

The andThen method allows chaining multiple BiConsumer operations.

package org.kodejava.util.function;

import java.util.function.BiConsumer;

public class BiConsumerAndThen {
  public static void main(String[] args) {
    BiConsumer<String, Integer> print =
            (key, value) ->
                    System.out.println("Key: " + key + ", Value: " + value);

    BiConsumer<String, Integer> multiplyValue =
            (key, value) ->
                    System.out.println("Multiplied Value for " + key + ": " + (value * 2));

    // Combine the two BiConsumers
    BiConsumer<String, Integer> combinedBiConsumer = print.andThen(multiplyValue);

    // Use the combined BiConsumer
    combinedBiConsumer.accept("Apples", 10);
  }
}

Output:

Key: Apples, Value: 10
Multiplied Value for Apples: 20

Scenarios to use BiConsumer:

  1. Iteration and processing:
    • Iterate through a Map and perform operations on key-value pairs.
  2. Side effects:
    • Logging, printing results, or modifying shared data structures.
  3. Chaining behaviors:
    • Chain operations on a pair of inputs using andThen.

Keynotes:

  • Be cautious about side effects as BiConsumer is typically used when a return value is not required.
  • The andThen method helps in composing behaviors, making the interface more powerful.

How do I use the Predicate functional interface in Java?

The Predicate class in Java is a functional interface introduced in Java 8 under the java.util.function package. It is used to test a condition on an input and return a boolean value (true or false). Predicates are often used in lambda expressions or method references to filter data or apply conditional logic.

Here’s how we can use the Predicate class in Java:

Basic Predicate Usage

The Predicate interface has a single abstract method:

boolean test(T t);

We implement this method to provide our condition logic.

Example:

package org.kodejava.util.function;

import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        // Create a predicate that checks if a number is greater than 10
        Predicate<Integer> isGreaterThan10 = number -> number > 10;

        // Test the condition
        System.out.println(isGreaterThan10.test(15)); // Output: true
        System.out.println(isGreaterThan10.test(8));  // Output: false
    }
}

Chaining Predicates

Predicates provide methods to combine multiple conditions:
and() – Combines two predicates with logical AND.
or() – Combines two predicates with logical OR.
negate() – Negates the predicate (logical NOT).

Example:

package org.kodejava.util.function;

import java.util.function.Predicate;

public class PredicateChainingExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = number -> number % 2 == 0;
        Predicate<Integer> isGreaterThan5 = number -> number > 5;

        // Chain predicates
        Predicate<Integer> isEvenAndGreaterThan5 = isEven.and(isGreaterThan5);
        Predicate<Integer> isEvenOrGreaterThan5 = isEven.or(isGreaterThan5);

        // Test
        System.out.println(isEvenAndGreaterThan5.test(8));  // Output: true
        System.out.println(isEvenAndGreaterThan5.test(3));  // Output: false
        System.out.println(isEvenOrGreaterThan5.test(3));   // Output: false
        System.out.println(isEvenOrGreaterThan5.test(7));   // Output: true
    }
}

Using Predicate in Collections

The Predicate interface is extensively used in working with Streams or filtering collections.

Example:

package org.kodejava.util.function;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateWithStreams {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Carol", "Mallory");

        // Create a predicate that tests if the string length is greater than 3
        Predicate<String> lengthGreaterThan3 = name -> name.length() > 3;

        // Filter and collect using the predicate
        List<String> filteredNames = names.stream()
                .filter(lengthGreaterThan3)
                .collect(Collectors.toList());

        // Output: [Alice, Carol, Mallory]
        System.out.println(filteredNames);
    }
}

Using Predicate with Default Methods

isEqual()

This static method evaluates if an object is equal to a predefined value.

Example:

package org.kodejava.util.function;

import java.util.function.Predicate;

public class PredicateIsEqualExample {
    public static void main(String[] args) {
        Predicate<String> isEqualToMark = Predicate.isEqual("Alice");

        // Output: true
        System.out.println(isEqualToMark.test("Alice"));
        // Output: false
        System.out.println(isEqualToMark.test("Bob"));
    }
}

Custom Predicate Usage

We can create our own predicate and pass it around in our code.

Example:

package org.kodejava.util.function;

import java.util.function.Predicate;

public class CustomPredicateExample {
    public static void main(String[] args) {
        // A custom method accepting a predicate
        testPredicate(value -> value > 10);

        // Another predicate for custom logic
        Predicate<Integer> isOdd = value -> value % 2 != 0;
        // Output: true
        System.out.println(isOdd.test(7));
    }

    static void testPredicate(Predicate<Integer> predicate) {
        // Output: true
        System.out.println(predicate.test(15));
    }
}

Summary

  • The Predicate interface is used for conditional checks and filtering data.
  • It works seamlessly with lambda expressions and method references.
  • You can combine multiple predicates using and, or, and negate.

This makes Predicate a very powerful and convenient tool for functional programming in Java!

How do I add an object to the beginning of Stream?

To add an object to the beginning of a list using Java Streams, we typically cannot directly prepend an object in a stream-friendly way because Streams themselves are immutable and don’t directly modify the original collection. However, we can achieve this by creating a new list with the desired order.

Here’s how we can approach it:

package org.kodejava.stream;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamBeginningAdd {
    public static void main(String[] args) {
        List<String> originalList = Arrays.asList("B", "C", "D");
        String newElement = "A";

        // Add the new element at the beginning using Stream
        List<String> updatedList = Stream.concat(Stream.of(newElement), originalList.stream())
                .collect(Collectors.toList());

        // Output: [A, B, C, D]
        System.out.println(updatedList);
    }
}

Explanation:

  1. Stream.of(newElement): Wraps the new element as a single-element stream.
  2. originalList.stream(): Converts the existing list into a stream.
  3. Stream.concat(): Combines the two streams — placing the newElement stream first and the original list’s stream second.
  4. collect(Collectors.toList()): Materializes (collects) the combined stream into a new list.

This ensures immutability of the original list and creates a new list with the desired order.

How do I get number of each day for a certain month in Java?

You can get the number of each day (Monday, Tuesday, etc.) for a specific month in Java using the java.time package introduced in Java 8. In the following code snippet we will use a loop to iterate the dates in the month. The number of loop is equals to the number of days in the month.

You can run this code to get the count of each day of the week for any specific month and year. Here’s a sample code to achieve that:

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.EnumMap;
import java.util.Map;

public class DaysOfWeekInMonthWithLoop {

    public static Map<DayOfWeek, Integer> getDaysCountForMonth(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate firstOfMonth = yearMonth.atDay(1);
        LocalDate lastOfMonth = yearMonth.atEndOfMonth();

        Map<DayOfWeek, Integer> daysCount = new EnumMap<>(DayOfWeek.class);

        for (DayOfWeek day : DayOfWeek.values()) {
            daysCount.put(day, 0);
        }

        for (LocalDate date = firstOfMonth; !date.isAfter(lastOfMonth); date = date.plusDays(1)) {
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            daysCount.put(dayOfWeek, daysCount.get(dayOfWeek) + 1);
        }

        return daysCount;
    }

    public static void main(String[] args) {
        int year = 2024;
        int month = 10; // October

        Map<DayOfWeek, Integer> daysCount = getDaysCountForMonth(year, month);

        for (Map.Entry<DayOfWeek, Integer> entry : daysCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

Output:

MONDAY: 4
TUESDAY: 5
WEDNESDAY: 5
THURSDAY: 5
FRIDAY: 4
SATURDAY: 4
SUNDAY: 4

What we do in the code snippet above:

  1. YearMonth: Used to represent the year and month. You create an instance of YearMonth for the desired year and month.
  2. LocalDate: Represents a date (year, month, day). firstOfMonth is the first day of the month and lastOfMonth is the last day of the month.
  3. EnumMap: A specialized map for use with enum keys, which in this case are days of the week (from DayOfWeek enum).
  4. Loop through Dates: Iterate from the first to the last day of the month. For each date, get the day of the week and update the count in the map.

Another solution that we can use is to calculate the number of days using a simple mathematical calculations instead of iterating through the dates of the month.

The refined approach:

  1. Determine the first day of the month.
  2. Calculate the base number of times each day appears:
    • Each day will appear at least daysInMonth / 7 times because every 7-day week will have each day once.
    • The remainder from daysInMonth % 7 will determine how many days are left over from complete weeks, starting from the first day of the month.

Here is how we can implement it:

package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.EnumMap;
import java.util.Map;

public class DaysOfWeekInMonth {

    public static Map<DayOfWeek, Integer> getDaysCountForMonth(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate firstDayOfMonth = yearMonth.atDay(1);

        int daysInMonth = yearMonth.lengthOfMonth();
        DayOfWeek firstDayOfWeek = firstDayOfMonth.getDayOfWeek();

        Map<DayOfWeek, Integer> daysCount = new EnumMap<>(DayOfWeek.class);

        int baseCount = daysInMonth / 7;
        int extraDays = daysInMonth % 7;

        for (DayOfWeek day : DayOfWeek.values()) {
            daysCount.put(day, baseCount);
        }

        for (int i = 0; i < extraDays; i++) {
            DayOfWeek currentDay = firstDayOfWeek.plus(i);
            daysCount.put(currentDay, daysCount.get(currentDay) + 1);
        }

        return daysCount;
    }

    public static void main(String[] args) {
        int year = 2024;
        int month = 10; // October

        Map<DayOfWeek, Integer> daysCount = getDaysCountForMonth(year, month);

        for (Map.Entry<DayOfWeek, Integer> entry : daysCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

Output:

MONDAY: 4
TUESDAY: 5
WEDNESDAY: 5
THURSDAY: 5
FRIDAY: 4
SATURDAY: 4
SUNDAY: 4

In this approach:

  1. YearMonth: Represents the year and month.
  2. LocalDate: Determines the first day of the month.
  3. DayOfWeek: Identifies the day of the week for the first day of the month.
  4. EnumMap: Stores the count of each day of the week.
  5. Base Count and Remainder:
    • baseCount: Calculates how many whole weeks (7 days) fit in the month.
    • extraDays: Calculates the remaining days after accounting for whole weeks.
    • Initialize each count in the map to baseCount.
    • Add 1 to the first extraDays days in the week starting from firstDayOfWeek.

This approach avoids explicitly iterating over each day in the month and relies on mathematical operations to determine the count of each day of the week.

How do I get operating system process information using ProcessHandle?

Java 9 introduced the ProcessHandle API, which allows us to interact with and retrieve information about native processes. Here’s how we can use ProcessHandle to get information about operating system processes:

We can list all the processes currently running on the system and print their details:

package org.kodejava.example.lang;

import java.time.Duration;
import java.time.Instant;

public class ProcessHandleExample {
    public static void main(String[] params) {
        ProcessHandle.allProcesses()
                .forEach(process -> {
                    long pid = process.pid();
                    ProcessHandle.Info info = process.info();
                    String cmd = info.command().orElse("");
                    String[] args = info.arguments().orElse(new String[0]);
                    Instant startTime = info.startInstant().orElse(null);
                    Duration cpuUsage = info.totalCpuDuration().orElse(Duration.ZERO);

                    System.out.println("PID        = " + pid);
                    System.out.println("Command    = " + cmd);
                    System.out.println("Args       = " + String.join(" ", args));
                    System.out.println("Start Time = " + startTime);
                    System.out.println("CPU Usage  = " + cpuUsage);
                    System.out.println("------------");
                });
    }
}

If we want to get information about a specific process, we can use their process ID (PID):

package org.kodejava.example.lang;

import java.time.Duration;
import java.time.Instant;
import java.util.Optional;

public class SpecificProcessInfo {
    public static void main(String[] params) {
        // Replace with the PID of the process you want to query
        long pid = 33656;

        // Get the ProcessHandle of the specific process
        Optional<ProcessHandle> processHandle = ProcessHandle.of(pid);
        if (processHandle.isPresent()) {
            ProcessHandle process = processHandle.get();
            pid = process.pid();
            ProcessHandle.Info info = process.info();
            String cmd = info.command().orElse("");
            String[] args = info.arguments().orElse(new String[0]);
            Instant startTime = info.startInstant().orElse(null);
            Duration cpuUsage = info.totalCpuDuration().orElse(Duration.ZERO);

            System.out.println("PID        = " + pid);
            System.out.println("Command    = " + cmd);
            System.out.println("Args       = " + String.join(" ", args));
            System.out.println("Start Time = " + startTime);
            System.out.println("CPU Usage  = " + cpuUsage);
            System.out.println("------------");
        } else {
            System.out.println("No process found with PID: " + pid);
        }
    }
}

Output:

PID        = 33656
Command    = C:\Users\wayan\AppData\Local\Programs\IntelliJ IDEA Ultimate\bin\idea64.exe
Args       = 
Start Time = 2024-07-22T03:14:07.825Z
CPU Usage  = PT46M27.484375S
------------

Explanation

  • ProcessHandle.allProcesses(): returns a stream of all processes currently running on the system.
  • ProcessHandle.of(pid): returns an Optional<ProcessHandle> for the process with the given PID.
  • ProcessHandle.Info: contains information about a process, such as its command, arguments, start time, and CPU usage.
  • info.command(): returns an Optional<String> with the command used to start the process.
  • info.arguments(): returns an Optional<String[]> with the arguments passed to the process.
  • info.startInstant(): returns an Optional<Instant> with the start time of the process.
  • info.totalCpuDuration(): returns an Optional<Duration> with the total CPU time used by the process.

Using the ProcessHandle API in Java 9 and later makes it straightforward to get detailed information about operating system processes.

How do I sum a BigDecimal property of a list of objects using Java Stream API?

If we have a list of objects, and we want to sum a BigDecimal property of these objects, we can achieve this using the Java Stream API. This API provides a clean and efficient way to process collections of objects. To sum the BigDecimal amounts, you can use the map and reduce methods of the Stream API.

As an example, we have a class named Transaction with a BigDecimal property named amount. We have a list of Transaction objects, and we want to calculate the total sum of the amount properties.

In the code snippet below we do the following:

  • Creating Transactions: We create a list of Transaction objects, each with a different BigDecimal amount.
  • Filter Transactions and its amount: We filter to exclude the null transaction and null transaction amount.
  • Mapping to Amounts: We use the map method to convert each Transaction object to its amount property.
  • Summing the Amounts: The reduce method takes two parameters: an identity value (BigDecimal.ZERO) and an accumulator function (BigDecimal::add). The accumulator function adds each BigDecimal in the stream to the running total.
  • Printing the Result: Finally, we print the total sum of the amounts.
package org.kodejava.stream;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

public class BigDecimalSumExample {
    public static void main(String[] args) {
        // Create a list of transaction objects
        List<Transaction> transactions = Arrays.asList(
                new Transaction(new BigDecimal("10.50")),
                null,
                new Transaction(new BigDecimal("30.25")),
                new Transaction(null),
                new Transaction(new BigDecimal("11.49"))
        );

        // Sum the amount properties using stream
        BigDecimal totalAmount = transactions.stream()
                // Filter out null Transaction objects and Transaction objects
                // with null amounts
                .filter(t -> t != null && t.getAmount() != null)
                .map(Transaction::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // Print the result
        System.out.println("Total Amount: " + totalAmount);
    }

    static class Transaction {
        private final BigDecimal amount;

        public Transaction(BigDecimal amount) {
            this.amount = amount;
        }

        public BigDecimal getAmount() {
            return amount;
        }
    }
}

Below is another example, we want to sum just a List<BigDecimal> values. To sum the values we can use the reduce method as shown in the code snippet below.

package org.kodejava.stream;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class BigDecimalListSumExample {
    public static void main(String[] args) {
        // Create a list of BigDecimal values
        List<BigDecimal> amounts = Arrays.asList(
                new BigDecimal("10.50"),
                new BigDecimal("20.75"),
                new BigDecimal("30.25"),
                null,
                new BigDecimal("11.49")
        );

        // Sum the BigDecimal values using stream
        BigDecimal totalAmount = amounts.stream()
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // Print the result
        System.out.println("Total Amount: " + totalAmount);
    }
}

Using Java Stream API to sum a BigDecimal property of a list of objects or a list of BigDecimal values are both concise and efficient. The map and reduce methods streamline the process, making our code more readable and maintainable. This approach can be applied to various scenarios where we need to aggregate data from a list of objects.

How do I convert date string from one format to another format?

In the following code snippet we will see hot to change a date from one format to another format. For example from 2024-11-04 to 04-Nov-24 format in Java. We can use the DateTimeFormatter class from the java.time.format package to do the conversion.

The steps are:

  • Parse the original date string.
  • Format it to the desired pattern.

Here’s the complete code to do this:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class DateFormatConversion {
    public static void main(String[] args) {
        // The original date string
        String originalDate = "2024-11-04";

        // Define the input and output date formats
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd-MMM-yy");

        // Parse the original date
        LocalDate date = LocalDate.parse(originalDate, inputFormatter);

        // Format the date to the desired pattern
        String formattedDate = date.format(outputFormatter);

        // Print the formatted date
        System.out.println(formattedDate);
    }
}

Output:

04-Nov-24

In the code above we define two formatters, one for the original date format, and the second one is for the new date format. The input formatter matches the original date format (yyyy-MM-dd). The output formatter specifies the desired format (dd-MMM-yy).

We use the LocalDate.parse() method to parse the string of original date into a LocalDate object. Next, we use the LocalDate.format() method to convert into a new date format using the defined formatter object.

This approach uses java.time API introduced in Java 8, which is the recommended way to handle date and time in Java due to its immutability and thread-safety features.

How do I update records in MS Access database?

In this post, we will learn how to update records in a database using the Java Database Connectivity (JDBC) API. JDBC is a Java API which is used to connect and execute query in the database.

We will be working with an MS Access database file named musicdb.accdb for this example. Our goal is to update an album’s title and release date in our album table.

The following code snippet show you how to do it. The selectAlbum() method is just a helper method to show the album data before and after the data was updated.

package org.kodejava.jdbc;

import java.sql.*;
import java.time.LocalDate;
import java.time.Month;

public class MSAccessUpdate {
    public static void main(String[] args) {
        String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb";
        try (Connection conn = DriverManager.getConnection(url)) {
            conn.setAutoCommit(false);
            selectAlbum(conn, 2L);

            String sql = """
                    update album
                        set title = ?,
                        release_date = ?
                    where id = ?
                    """;

            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, "A Hard Day's Night");
            ps.setDate(2, Date.valueOf(LocalDate.of(1964, Month.JULY, 10)));
            ps.setLong(3, 2);

            int rowCount = ps.executeUpdate();
            System.out.printf("%s (rows) updated.%n", rowCount);

            selectAlbum(conn, 2L);

            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * Executes a SQL query to select an album from the database based on the
     * provided ID.
     *
     * @param conn the Connection object representing the database connection
     * @param id   the ID of the album to be selected
     * @throws SQLException if a database access error occurs or the SQL query
     * is invalid
     */
    private static void selectAlbum(Connection conn, Long id) throws SQLException {
        String sql = "select * from album where id = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setLong(1, id);

        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            System.out.printf("id=%s, title=%s, released_date=%s%n",
                    rs.getLong("id"), rs.getString("title"),
                    rs.getDate("release_date"));
        }
    }
}

The following is an output produced by the code snippet above:

id=2, title=With the Beatles, released_date=1963-11-22
1 (rows) updated.
id=2, title=A Hard Day's Night, released_date=1964-07-10

Maven Dependencies

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

Maven Central

How do I insert a record into Microsoft Access database and get the generated key?

In this tutorial, we’ll guide you through the process of inserting records into an MS Access Database. In the code snippet below we are using the UCanAccess JDBC driver, you can find the Maven dependencies at the end of this tutorial.

Setting Up The Connection

Firstly, we need to set up a connection to our MS Access database. This is done by specifying the path of your database file (.mdb or .accdb) in the JDBC URL and then getting a connection from DriverManager.

String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb";
try (Connection connection = DriverManager.getConnection(url)) {
    ...
} catch (SQLException e) {
    e.printStackTrace();
}

Preparing the SQL Statement

Next step is to prepare our SQL insert statement. We use a PreparedStatement – it handles the tedious task of substituting the respective parameters into the placeholders ("?") in our SQL statement.

String sql = "insert into album (title, release_date, created) values (?, ?, ?)";

PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

Setting Parameters and Executing the SQL Statement

After defining our SQL statement with placeholders, we replace these placeholders with actual values using the setter methods (setInt(), setString(), setDate(), etc.) provided by the PreparedStatement class. Once, the placeholders have been replaced with actual values, we call executeUpdate() method on the PreparedStatement object to execute the SQL statement.

ps.setString(1, "With the Beatles");
ps.setDate(2, Date.valueOf(LocalDate.of(1963, Month.NOVEMBER, 22)));
ps.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
int rowCount = ps.executeUpdate();
System.out.println("rowCount = " + rowCount);

In the code snippet above we set all placeholders with values we want to insert into the database, and then the statement is executed. The new record gets added to the database. We also keep the rowCount returned by the executeUpdate() method.

Get the Generated Key Value

When creating the PreparedStatement object we also passes the Statement.RETURN_GENERATED_KEYS parameter, this will allow us to get the generated key from the statement object after executing the query.

ResultSet generatedKeys = ps.getGeneratedKeys();
long generatedKey = 1L;
while (generatedKeys.next()) {
    generatedKey = generatedKeys.getLong(1);
}
System.out.println("Generated Key = " + generatedKey);

The Entire Code Snippet

Here is the entire Java class.

package org.kodejava.jdbc;

import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;

public class MSAccessInsert {
    public static void main(String[] args) {
        String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb";
        try (Connection connection = DriverManager.getConnection(url)) {
            String sql = "insert into album (title, release_date, created) values (?, ?, ?)";

            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setString(1, "With the Beatles");
            ps.setDate(2, Date.valueOf(LocalDate.of(1963, Month.NOVEMBER, 22)));
            ps.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));

            int rowCount = ps.executeUpdate();
            System.out.println("rowCount = " + rowCount);

            ResultSet generatedKeys = ps.getGeneratedKeys();
            long generatedKey = 1L;
            while (generatedKeys.next()) {
                generatedKey = generatedKeys.getLong(1);
            }
            System.out.println("Generated Key = " + generatedKey);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

The code above inserts a new record into the album table in the Access database. Remember to handle any SQLException that may be thrown while interacting with the database.

And that’s it! You have successfully inserted a record into an MS Access database using UCanAccess in Java. Whether you’re creating a small application or dealing with large-scale data management, UCanAccess is an easy, efficient way to work with MS Access databases in Java applications.

Maven Dependencies

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

Maven Central

How do I select a record from Microsoft Access Database?

UCanAccess is a pure Java JDBC Driver implementation which allows Java developers and JDBC client programs to read and write Microsoft Access database files (.mdb and .accdb).

In this tutorial, we will demonstrate how to configure a project with UCanAccess and create a simple Java application to select data from an MS Access database.

Establishing a Connection

Before you can interact with a database, you need to establish a connection to it. The following is an example of how to establish a connection using UCanAccess:

String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb;";
try (Connection connection = DriverManager.getConnection(url)) {
    System.out.println("connection = " + connection);
    // Rest of the code goes here...
} catch (SQLException e) {
    e.printStackTrace();
}

In the code above, we create a connection URL using the absolute path to our Access database file. Then, we obtain a connection object by calling DriverManager.getConnection(url).

Fetching Data from the Database

Once the connection is established, we can execute SQL queries against the database. Here, let’s create a query to select some data:

String query = "select id, title, release_date from album where id = ?";

PreparedStatement ps = connection.prepareStatement(query);
ps.setLong(1, 1L);

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    System.out.printf("id=%s, title=%s, released_date=%s%n",
            rs.getLong("id"), rs.getString("title"),
            rs.getDate("release_date"));
}

In this code, we create a PreparedStatement object, which enables us to execute parameterized SQL queries in a secure and efficient manner. Here, our SQL query includes a parameter, represented by the ? symbol, which we then set using setLong(). This would replace the ? with the value 1L.

We then execute our query by calling executeQuery() on the PreparedStatement object which returns a ResultSet object. This object represents the result set of the query.

We then loop through the result set and print each record using rs.next(), which is used to iterate through the ResultSet.

Full Code

package org.kodejava.jdbc;

import java.sql.*;

public class MSAccessSelect {
    public static void main(String[] args) {
        String url = "jdbc:ucanaccess://C:/Users/wayan/Temp/musicdb.accdb;";
        try (Connection connection = DriverManager.getConnection(url)) {
            System.out.println("connection = " + connection);

            String query = "select id, title, release_date from album where id = ?";

            PreparedStatement ps = connection.prepareStatement(query);
            ps.setLong(1, 1L);

            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                System.out.printf("id=%s, title=%s, released_date=%s%n",
                        rs.getLong("id"), rs.getString("title"),
                        rs.getDate("release_date"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Remember to handle SQL exceptions that might be thrown during the interaction with the database. And there you have it! Now you know how to work with MS Access Database using UCanAccess in Java. Happy coding!

Maven Dependencies

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

Maven Central