Skip to main content

Objects and Relational Data

To set the stage here, I want to examine a different perspective through which an object-oriented programming language can approach data persisted in a relation database, in the context of the most popular approach today, which is using some form of an ORM. For the purposes of examining any concrete concept, I will stick to Java for the implementation details.

I will begin with a brisk walk down memory-lane. If you have worked with Java long enough, I'm sure you'll remember a time when there was only jdbc, and if you were super-advanced (at the time), there was spring-jdbc - there wasn't hibernate which nowadays is all too common. The basic operations involved with jdbc were (and still are) very imperative

  • Create properties
  • Initialize a datasource
  • Borrow a connection
  • Use this connection to interact with the database
  • Release the connection
  • Before exiting the application, destroy the datasource

Ignoring concepts like transactions and isolation levels, allow me to briefly elaborate on these steps

Create Properies#

There are many ways you can create properties, and below is one such, very basic way

Properties properties = new Properties();properties.load(...) //load from some configurable sourceproperties.setProperty("database.jdbcUrl", "jdbc:postgresql://localhost:5432/postgres");properties.setProperty("database.username", "postgres");properties.setProperty("database.password", "postgres");properties.setProperty(...) //add more properties as need be

Initialize a datasource#

As is common in Java, there is an almost overwhelming abundance of libraries to accomplish a task - this can be both a blessing and a curse. Creating a datasource is one activity that you almost always want to use a well-established datasource connection pool, and in the example below, I make use of HikariCP

Properties properties = connectionProperties(); //get your propertiesHikariConfig config = new HikariConfig();config.setJdbcUrl(properties.getProperty("database.jdbcUrl"));config.setUsername(properties.getProperty("database.username"));config.setPassword(properties.getProperty("database.password"));//configure additional properties as need beHikariDataSource ds = new HikariDataSource(config);

Borrow a connection#

Borrowing a connection is handled transparently by the datasource, and it's as simple as using its get operaiton

Connection getConnection() throws SQLException {   return ds.getConnection();}

Interacting with the database#

Interacting with the database varies significanty depending on which operation you are performing - INSERT, SELECT, UPDATE, DELETE. In this example, this is a minimalistic setup you would potentially leverage for a SELECT operation

try (Connection connection = /*use suitable mechanism to borrow a connection*/) {   //try-with-resource will automatially release the borrowed connection when the current scope is exited  //handle you database concerns    return handleDatabaseOperation(connection);} catch (Exception e) {    log.error(errorMessage, e);    throw new RuntimeException(errorMessage, e); //major pain in the **** with Java}

Release the connection#

Releasing the connection is handled automatically by the try-with-resources construct while destroying the datasource should be handled using any appropriate method that gets the goal accomplished, for example using a shutdown hook to be notified when the JVM is exiting so that the datasource can be closed just prior

In the next scetion, I will examine the SELECT operation, and may be learn some lessones that can be extended to the other operations as well.