{"id":18595437,"url":"https://github.com/svenruppert/jdbc-dao","last_synced_at":"2025-04-10T16:31:28.429Z","repository":{"id":54887885,"uuid":"67490484","full_name":"svenruppert/JDBC-DAO","owner":"svenruppert","description":"minimalistic JDBC based DAO","archived":false,"fork":false,"pushed_at":"2021-01-22T06:44:23.000Z","size":152,"stargazers_count":10,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-03-25T00:51:09.399Z","etag":null,"topics":["connection-pool","dao","design-pattern","functional","java","java8","java9","jdbc-dao","rdbms","sql"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/svenruppert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-06T08:45:42.000Z","updated_at":"2024-02-10T22:09:51.000Z","dependencies_parsed_at":"2022-08-14T05:50:25.675Z","dependency_job_id":null,"html_url":"https://github.com/svenruppert/JDBC-DAO","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2FJDBC-DAO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2FJDBC-DAO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2FJDBC-DAO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svenruppert%2FJDBC-DAO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/svenruppert","download_url":"https://codeload.github.com/svenruppert/JDBC-DAO/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248252691,"owners_count":21072701,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["connection-pool","dao","design-pattern","functional","java","java8","java9","jdbc-dao","rdbms","sql"],"created_at":"2024-11-07T01:19:45.797Z","updated_at":"2025-04-10T16:31:26.008Z","avatar_url":"https://github.com/svenruppert.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JDBC-DAO - a minimalistic JDBC based DAO\n\nSometimes you have a small project with a minimal database and you don´t want to \nstart with one of the big ORM frameworks.\nFor this I extracted the few classes here to give a minimalistic base.\n\nFeel free to use.  If you have any comments...  @SvenRuppert or sven.ruppert at gmail\n\n## The short version\n\n![Overview](./UserDAOHSQL.png)\n\n\n## Example\n\nFor this example (you could find it in the src-test folder)\n I created a class \"User\" We could call it our model.\n \n ```java\n public class User {\n \n   private final Integer customerID;\n   private final String firstname;\n   private final String lastname;\n   private final String email;\n   //SNIPP\n ```\n\nbtw: For this implementation the JDBC Connection Pool HikariCP is used.\n\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.zaxxer\u003c/groupId\u003e\n      \u003cartifactId\u003eHikariCP\u003c/artifactId\u003e\n    \u003c/dependency\u003e\n```\nSo, lets define the minimum we need for every Operation, a SQL String.\nFor this we are defining the method ***String createSQL()***.\n\n```java\n@FunctionalInterface\npublic interface BasicOperation {\n\n  String createSQL();\n}\n```\n\nWith this we could start to define all the generic JDBC stuff we need for our project.\nMaybe a generic ***Update*** Operation. \n\n```java\n@FunctionalInterface\npublic interface Update extends BasicOperation {\n\n  default int update(final JDBCConnectionPool connectionPool) {\n    final HikariDataSource dataSource = connectionPool.getDataSource();\n    try {\n      final Connection connection = dataSource.getConnection();\n      final int count;\n      try (final Statement statement = connection.createStatement()) {\n        final String sql = createSQL();\n        count = statement.executeUpdate(sql);\n        statement.close();\n      }\n      dataSource.evictConnection(connection);\n      return count;\n    } catch (final SQLException e) {\n      e.printStackTrace();\n    }\n    return -1;\n  }\n\n}\n```\n\nThis implementation is only the generic part from the technical point of view.\nIt combines the Connection-Pool with the JDBC-statement to execute a SQL command.\nNothing more happened here. I implemented this as an interface with a default implementation, \nso we could combine later command implementations if we would like.\n\nOne thing all DAO classes will have, is the possibility to get an Connection-Pool\nto execute SQL Commands.\n\n```java\n@FunctionalInterface\npublic interface DAO {\n  JDBCConnectionPool connectionPool();\n}\n```\n\nNow, lets have a look at the part that will combine this with the model. (Class User)\nTo implement a DAO you don´t have to extend a class. Just define the methods you need.\nWe are using this interface only to describe the RDBMS Vendor independent things.\n\nIn this case, the method ***writeUser*** in combination with the \nmethod signature ***createInsert***\n\n```java\npublic interface UserDAO extends DAO {\n\n  default void writeUser(final User user) {\n    ((Update) () -\u003e createInsert(user)).update(connectionPool());\n  }\n\n  String createInsert(User user);\n\n  //SNIPP\n}\n```\n\nHere I divided the task into two parts. \nPart number one is the definition of an ***Update*** operation with the \nreference to the method that will create a SQL String based on the User.\nPart number two is the invocation of the method update itself and the Connection-Pool \nthat must be used. ( method definition ***connectionPool()*** )\n\nHow to get the ConnectionPool is not defined here. This is a technical part, based on the project \nand the possibilities there. It could be static or Dependency Injection or.. \n\nUntil now we have no RDBMS vendor specific code written.\n\nThe next step will be an infrastructure step. It will combine the right ConnectionPool.\nNow we nee to hold the instance, that will force us to make a abstract class out of it.\n\n```java\npublic abstract class GenericDAO implements DAO {\n\n  private JDBCConnectionPool connectionPool;\n\n  public UserDAOAbstractImpl workOnPool(final JDBCConnectionPool connectionPool) {\n    this.connectionPool = connectionPool;\n    return this;\n  }\n\n  @Override\n  public JDBCConnectionPool connectionPool() {\n    return connectionPool;\n  }\n\n}\n```\nThis abstract class only presents a way, how to connect the ConnectionPool with the DAO itself.\nIn this example we are using a set-method (***workOnPool***). But it could be an @Inject as well.\n\nNow it is time to write the SQL for your RDBMS.\n```java\npublic class UserDAOHSQL extends UserDAOAbstractImpl \n                         implements UserDAO {\n\n  public String createInsert(final User user) {\n    final String sql = \"INSERT INTO CUSTOMER \" +\n        \"( CUSTOMER_ID, FIRSTNAME, LASTNAME, EMAIL ) \" +\n        \" VALUES \" +\n        \"( \" +\n        user.getCustomerID() + \", \" +\n        \"'\" + user.getFirstname() + \"', \" +\n        \"'\" + user.getLastname() + \"', \" +\n        \"'\" + user.getEmail() + \"' \" +\n        \")\";\n    return sql;\n  }\n\n  //SNIPP\n}\n```\nHere we are implementing a HSQL version of this DAO. \nThe only thing is the transformation of the User to the SQL String.\nIf we would like to have an Oracle version of this, \nwe could create a class ***UserDAOOracle***\n\nFinally we are done.\nBased on this we could realize jUnit tests that are working with the UserDAO interface.\nWith this we are able to define one test and see if every implementation will have the same behavior.\n\nIn this project I gave you an example how to start an In-Memory HSQL DB to deal with jUnit.\nFeel free to use, and let me know what you are thinking about it.\n\nHave in mind, that this is only a very small implementation \nand nothing you should compare with frameworks like JOOQ or Speedment or JPA or..\nBut it is easy to use ;-)\n\nFeel free to change and extend..  ;-)\n\nIf you have questions, the best easiest ways to reach me are\n\nmail: sven.ruppert (at) gmail.com or Twitter @SvenRuppert\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvenruppert%2Fjdbc-dao","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsvenruppert%2Fjdbc-dao","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvenruppert%2Fjdbc-dao/lists"}