JDBC is one of the most often-used APIs in Java. Whether we are programming for phones, tablets, laptops, or servers in the cloud, we often have to work with a database. JDBC is the Java-based technology used to facilitate Java programs interacting (INSERT, UPDATE, DELETE, SELECT) with RDBMS technologies. Having been refined over twenty years it is a fairly mature and robust part of the Java technology stack. But it could be better? When it comes to working with query results, it could be much better. How? Here are a few of the things that it would be cool to have in the JDBC API:

  • Named Parameters
  • Mappings from ResultSet to Collections
  • Object-Oriented Filtering
  • Object-Oriented Grouping

Anyone who has every written a data access object by hand knows what I mean. The object-oriented coolness of Java PIE (Polymorphism, Inheritance, and Encapsulation) are largely lost as we are forced to work with ResultSet objects. In this post we will look briefly at using lambda functions to pass code as data. In particular we will use a block of code that publishes the current time every second as behavior for a thread.

import java.time.LocalDateTime;

/**
 * Simple example of using a lambda expression to pass asynchronous
 * behavior requiring no parameters as data.
 * @author Roderick L. Barnes, Sr.
 */
public class Example001 {
	/**
	 * I dislike the messiness of putting a try catch block in the salient block
	 * of code for the mere purpose trapping the exception that could be thrown
	 * by {@code Thread.sleep}.
	 * @param intSleepDurationInMilliseconds duration of sleep in milliseconds.
	 */
	public static void sleep(int intSleepDurationInMilliseconds) {
		try {
			Thread.sleep(intSleepDurationInMilliseconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * A basic test harness for the runnable lambda expression.
	 * @param arrayOfString unused by the test harness
	 */
	public static void main(String[] arrayOfString) {
		/**
		 * Step 1: Define a lambda expression that allows us to use behavior as data.
		 */
		Runnable runnableLambdaExpression = () -> {
				for (int intLoopIndex = 1; intLoopIndex < 10; intLoopIndex++) {
					System.out.println(LocalDateTime.now());
					
					Example001.sleep(1000);
				}
			};
		
		/**
		 * Step 2: Create the thread using the lambda and start the thread.
		 */
		Thread threadLambda = new Thread(runnableLambdaExpression);
		threadLambda.start();
	}
}

more text goes here.


import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.function.Predicate;
/** * Simple example of using a lambda expression to map one value to another. In this case * a date is mapped to a boolean value indicating whether or not it is a weekday. * @author Roderick L. Barnes, Sr. */ public class Example002 { /** * Constant for the JDBC driver used to connect to the database. */ private static final String STRING_JDBC_DRIVER = "org.postgresql.Driver"; /** * Constant for the URL that will be used by the JDBC driver to connect to the database. */ private static final String STRING_JDBC_DATABASE_URL = "jdbc:postgresql://bifproductsdb.ctrlzjj4vv8c.us-east-1.rds.amazonaws.com:5432/postgres"; /** * Constant for the user account that will be used to connect to the database. */ private static final String STRING_JDBC_USERNAME = "denzel_washington"; /** * Constant for the password that will be used to connect to the database. */ private static final String STRING_JDBC_PASSWORD = "book_of_eli"; /** * Returns the name of the class providing the JDBC driver functionality * for connections to the database. * @return the name of the JDBC driver class. */ private static String getJDBCDriver() { return Example002.STRING_JDBC_DRIVER; } /** * Returns the URL for the COVID-19 database. * @return the URL for the COVID-19 database. */ private static String getJDBCURL() { return Example002.STRING_JDBC_DATABASE_URL; } /** * Returns the username for the account that will be used to login to the database. * @return the username for the account that will be used to login to the database. */ private static String getJDBCUsername() { return Example002.STRING_JDBC_USERNAME; } /** * Returns the password for the account that will be used to login to the database. * @return the password for the account that will be used to login to the database. */ private static String getJDBCPassword() { return Example002.STRING_JDBC_PASSWORD; } /** * Test harness for the lambda function example. */ public static void main(String[] arrayOfString) throws ClassNotFoundException { /** * Step 1: Create a lambda function that returns a boolean value indicating whether * or not the given date is a weekday. The Predicate lambda function is used. */ Predicate isWeekday = (Date dateNew) -> { Instant instant = Instant.ofEpochMilli(dateNew.getTime()); LocalDate localDate = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate(); boolean booleanIsWeekDay = false; switch (localDate.getDayOfWeek()) { case MONDAY: case TUESDAY: case WEDNESDAY: case THURSDAY: case FRIDAY: booleanIsWeekDay = true; break; case SATURDAY: case SUNDAY: booleanIsWeekDay = false; break; } return booleanIsWeekDay; }; /** * Step 2: Load the required PostgreSQL JDBC driver into the virtual machine. */ Class.forName(Example002.getJDBCDriver()); /** * Step 3: Create a {@code String} for the SQL query that will get the data. */ String stringCOVID19Query = "SELECT " + "rr.record_date, " + "SUM(rr.confirmed) AS confirmed, " + "SUM(rr.recovered) AS recovered, " + "SUM(rr.deaths) AS deaths " + "FROM disease_tracking.regional_record rr " + "GROUP BY rr.record_date " + "ORDER BY rr.record_date ASC"; try ( /** * Step 3: Create the objects needed for the connection and query. */ Connection connection = DriverManager.getConnection( Example002.getJDBCURL(), Example002.getJDBCUsername(), Example002.getJDBCPassword() ); PreparedStatement preparedStatement = connection.prepareStatement(stringCOVID19Query); ) { /** * Step 4: Get a {@code ResultSet} for the query using a try-with-resources * block. */ try ( ResultSet resultSet = preparedStatement.executeQuery(); ) { /** * Step 5: Use the traditional approach to printing the {@code ResultSet}. */ while (resultSet.next()) { /** * Step 5.1: Print the date the disease information was collected. */ System.out.printf("%1$tY-%1$tm-%1$td",resultSet.getDate("record_date")); /** * Step 5.2: Use a lambda function to indicate whether or not it was a * weekday. */ System.out.printf("%7b%n", isWeekday.test(resultSet.getDate("record_date"))); } } } catch (SQLException sqlException) { sqlException.printStackTrace(); } } }