{"id":36417065,"url":"https://github.com/codurance/light-access","last_synced_at":"2026-01-11T17:00:14.869Z","repository":{"id":48311687,"uuid":"93067466","full_name":"codurance/light-access","owner":"codurance","description":null,"archived":false,"fork":false,"pushed_at":"2021-08-02T07:56:44.000Z","size":149,"stargazers_count":48,"open_issues_count":1,"forks_count":5,"subscribers_count":16,"default_branch":"master","last_synced_at":"2023-12-17T18:20:33.713Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://light-access.codurance.com/","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/codurance.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":"2017-06-01T14:42:40.000Z","updated_at":"2023-08-29T07:14:43.000Z","dependencies_parsed_at":"2022-09-26T21:40:39.438Z","dependency_job_id":null,"html_url":"https://github.com/codurance/light-access","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/codurance/light-access","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codurance%2Flight-access","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codurance%2Flight-access/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codurance%2Flight-access/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codurance%2Flight-access/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codurance","download_url":"https://codeload.github.com/codurance/light-access/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codurance%2Flight-access/sbom","scorecard":{"id":298405,"data":{"date":"2025-08-11","repo":{"name":"github.com/codurance/light-access","commit":"d5443ca42838c7a131672dd90f2e3f23ae0d4c64"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 3/26 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T20:06:35.689Z","repository_id":48311687,"created_at":"2025-08-17T20:06:35.689Z","updated_at":"2025-08-17T20:06:35.689Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28314253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-01-11T17:00:12.633Z","updated_at":"2026-01-11T17:00:14.820Z","avatar_url":"https://github.com/codurance.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CircleCI](https://circleci.com/gh/codurance/light-access/tree/master.svg?style=shield)](https://circleci.com/gh/codurance/light-access/tree/master)\n\nLight Access\n============\n\nLight Access is a small library on top of [JDBC][1], under the [Apache 2](https://www.apache.org/licenses/LICENSE-2.0) license. \n\n# Who should use this library?\n\nThis library is for Java developers who:\n \n* Want full control of their code.\n* Want a nice and fluid API on top of JDBC, using lambdas.\n* Prefer to use non-intrusive small libraries instead of intrusive ORM frameworks.\n* Want to reduce boiler plate code from their repositories.\n* Don't want to deal with JDBC's complexities and annoying exception handling.\n* Don't like to use any sort of automatic binding between their data structures and database.\n\n\n# Table of Contents\n\n1. [Installing LightAccess](#installation)\n2. [Getting started](#start)\n3. [DDL statements](#ddlstatements) \n    1. [DDLCommand](#ddlcommand)\n    2. [Executing multiple DDL commands](#multipleddlstatements)\n4. [DML statements](#dmlstatements)\n    1. [Select - single result](#selectsingleresult)\n    2. [Select - multiple results](#selectmultipleresults)\n    3. [Normalising one to many joins](#onetomanyjoins)    \n    4. [Insert](#insert)\n    5. [Update](#update)\n    6. [Delete](#delete)\n    7. [Statement, PreparedStatement and CallableStatement](#jdbcstatements)\n5. [Further documentation](#furtherdocumentation)\n    1. [Databases tested](#databases)\n6. [History](#history)\n\n\n\u003ca name=\"installation\"\u003e\u003c/a\u003e\n## Installing Light Access \n\n**Maven**\n\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.codurance\u003c/groupId\u003e\n      \u003cartifactId\u003elight-access\u003c/artifactId\u003e\n      \u003cversion\u003e0.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n**Gradle**    \n    \n    compile group: 'com.codurance', name: 'light-access', version: '0.1.0'    \n\n\u003ca name=\"start\"\u003e\u003c/a\u003e    \n## Getting started \n\nThe main class to look at is [LightAccess][2]. We recommend to have this class injected into your [repositories][3]. \n\nLightAccess receives a Datasource in its constructor and you can pass a connection pool to it. Let's do it using [h2][4].  \n\n```Java\nimport com.codurance.lightaccess.LightAccess;\nimport org.h2.jdbcx.JdbcConnectionPool;\n``` \n\n```Java\nJdbcConnectionPool jdbcConnectionPool = JdbcConnectionPool.create(\"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1\", \"user\", \"password\");\nLightAccess lightAccess = new LightAccess(jdbcConnectionPool);\n``` \n\n\u003ca name=\"ddlstatements\"\u003e\u003c/a\u003e       \n## Executing DDL statements     \n\nFirst let's define a DDL statement which create a table called 'products' with 3 fields. \n\n```java\n    private static final String CREATE_PRODUCTS_TABLE = \n        \"CREATE TABLE products (id integer PRIMARY KEY, name VARCHAR(255), date TIMESTAMP)\";\n```\n\nSo now, the only thing we need to do is to use the LightAccess to execute this DDL command.\n\n```java\n    lightAccess.executeDDLCommand((conn) -\u003e conn.statement(CREATE_PRODUCTS_TABLE).execute());\n``` \n\nAnd that's it. No exception handling or dealings with database connections. It is all handled for you.\n\nAlternatively, you can extract the lambda to a method. \n\n```java\n    private DDLCommand createProductsTable() {\n        return (conn) -\u003e conn.statement(CREATE_PRODUCTS_TABLE).execute();\n    }\n```\n\nAnd use it like this. \n\n```java\n    lightAccess.executeDDLCommand(createProductsTable());\n```\n\n\u003ca name=\"ddlcommand\"\u003e\u003c/a\u003e\n### DDLCommand \n\nThe `LightAccess.executeDDLCommand(DDLCommand command)` receives a `DDLCommand` as parameter. \n\n```java\n    public interface DDLCommand {\n        void execute(LAConnection connection) throws SQLException;\n    }\n```   \n\nWith that, you can pass in any lambda that satisfy the `execute(LAConnection connection)` method signature.\n\n\u003ca name=\"multipleddlstatements\"\u003e\u003c/a\u003e\n### Executing multiple DDL statements\n\nIt is possible to execute multiple commands in one go:\n\n```java\n    private static final String CREATE_USERS_TABLE = \"CREATE TABLE users (userId integer PRIMARY KEY, name VARCHAR(255))\";\n    private static final String CREATE_WISHLISTS_TABLE = \"CREATE TABLE wishlists (wishListId integer PRIMARY KEY, userId integer, name VARCHAR(255), creationDate TIMESTAMP)\";\n    private static final String CREATE_PRODUCTS_TABLE = \"CREATE TABLE products (productId integer PRIMARY KEY, name VARCHAR(255), date TIMESTAMP)\";\n    private static final String CREATE_WISHLIST_PRODUCT_TABLE = \"CREATE TABLE wishlist_product (id integer PRIMARY KEY, wishListId integer, productId integer)\";\n```\n\n```java\n    public void create_all_tables() {\n        lightAccess.executeDDLCommand(createTables());\n    }\n    \n    private DDLCommand createTables() {\n        return (conn) -\u003e {\n            conn.statement(CREATE_USERS_TABLE).execute();\n            conn.statement(CREATE_WISHLISTS_TABLE).execute();\n            conn.statement(CREATE_PRODUCTS_TABLE).execute();\n            conn.statement(CREATE_WISHLIST_PRODUCT_TABLE).execute();\n        };\n    }\n``` \n\n\u003ca name=\"dmlstatements\"\u003e\u003c/a\u003e\n## Executing DML statements\n\nLet's assume we have an object `Product` that we want to map to the `products` table. \n\n```java\n    public class Product {\n        private int id;\n        private String name;\n        private LocalDate date;    \n        \n        Product(int id, String name, LocalDate date) {\n            this.id = id;\n            this.name = name;\n            this.date = date;\n        }\n    \n        // getters\n        \n        // equals and hashcode    \n    }\n```   \n\n\u003ca name=\"selectsingleresult\"\u003e\u003c/a\u003e\n### Select - single result \n\nLet's take the following select statement.\n\n```java\n    private static final String SELECT_PRODUCT_BY_ID_SQL = \"select * from products where id = ?\";\n```\n\nNow let's create a method that returns a lambda for this select statement. As we are looking for a single entity and \nwe may not find it, it would be good if our query (`SQLQuery`) returned an `Optional\u003cProduct\u003e`.  \n\n```java\n    private SQLQuery\u003cOptional\u003cProduct\u003e\u003e retrieveProductWithId(int id) {\n        return conn -\u003e conn.prepareStatement(SELECT_PRODUCT_BY_ID_SQL)\n                            .withParam(id)\n                            .executeQuery()\n                            .onlyResult(this::toProduct);\n    }\n```\n\nIn case we find a product with this ID, we need to map the result set to the Product object. This is done in the \n`toProduct` method passed to `.onlyResult()` above.\n\n```java\n    private Product toProduct(LAResultSet laResultSet) {\n        return new Product(laResultSet.getInt(1),\n                           laResultSet.getString(2),\n                           laResultSet.getLocalDate(3));\n    }\n```\n\nNow we only need to execute the select statement. \n\n```java\n    Optional\u003cProduct\u003e product = lightAccess.executeQuery(retrieveProductWithId(10));\n```\n\nIn case you prefer an inline version, you can use:\n\n```java\n    Optional\u003cProduct\u003e product = lightAccess.executeQuery(conn -\u003e conn.prepareStatement(SELECT_PRODUCT_BY_ID_SQL)\n                                                                        .withParam(PRODUCT_TWO.id)\n                                                                        .executeQuery()\n                                                                        .onlyResult(this::toProduct));\n```\n\n\u003ca name=\"selectmultipleresults\"\u003e\u003c/a\u003e\n### Select - multiple results \n\nLet's take the following select statement:\n\n```java\n    private static final String SELECT_ALL_PRODUCTS_SQL = \"select * from products\";\n```\n\nNow let's create a method that returns a lambda:\n\n```java\n    private SQLQuery\u003cList\u003cProduct\u003e\u003e retrieveAllProducts() {\n        return conn -\u003e conn.prepareStatement(SELECT_ALL_PRODUCTS_SQL)\n                            .executeQuery()\n                            .mapResults(this::toProduct);\n    }\n```\n\nNote that now we are calling `mapResults(this::toProduct)` instead of `onlyResult(this::toProduct)`, and the `SQLQuery` \nis parameterised to return `List\u003cProduct\u003e`.\n\nNow we just need to invoke the query like before. \n\n```java\n    List\u003cProduct\u003e products = lightAccess.executeQuery(retrieveAllProducts());\n```\n\nAnd in case you prefer the inlined version:\n\n```java\n    List\u003cProduct\u003e products = lightAccess.executeQuery(conn -\u003e conn.prepareStatement(SELECT_ALL_PRODUCTS_SQL)\n                                                                    .executeQuery()\n                                                                    .mapResults(this::toProduct));\n```\n\n\u003ca name=\"onetomanyjoins\"\u003e\u003c/a\u003e\n### Normalising one to many joins\n\nLet's say we have a table with users and a table with wish lists:\n\n```sql\nCREATE TABLE users (userId integer PRIMARY KEY, name VARCHAR(255));\nCREATE TABLE wishlists (wishListId integer PRIMARY KEY, userId integer, name VARCHAR(255), creationDate TIMESTAMP);\n```\n\nNow let's assume we want to have all users and their respective wish lists, including the users without wish list. \n\n```sql\nselect u.userId, u.name, w.wishListId, w.userId, w.name, w.creationDate\n    from users u \n    left join wishlists w on u.userId = w.userId\n```\n\nWe want the result to be stored in a list containing the following DTO:\n\n```java\n    public class UserWithWishList {\n    \n        private final User user;\n        private final List\u003cWishList\u003e wishLists;\n    \n        public UserWithWishList(User user, List\u003cWishList\u003e wishLists) {\n            this.user = user;\n            this.wishLists = unmodifiableList(wishLists);\n        }\n    \n        // getters, equals, hashcode.\n    }\n```\n\nFor this to work we need to have a DTO for user and a DTO for the wish list:\n\n```java\n   public class User {\n   \n       private final Integer id;\n       private final String name;\n   \n       public User(Integer id, String name) {\n           this.id = id;\n           this.name = name;\n       }\n\n       // getters, equals, hashcode.\n    }\n```\n\n```java\n    public class WishList {\n    \n        private final Integer id;\n        private final Integer userId;\n        private final String name;\n        private final LocalDate creationDate;\n    \n        public WishList(Integer id, Integer userId, String name, LocalDate creationDate) {\n            this.id = id;\n            this.userId = userId;\n            this.name = name;\n            this.creationDate = creationDate;\n        }\n    }\n```\n\nSo now we are ready to get a list of `UserWithWishList` objects:\n\n```java\n\n    public List\u003cUserWithWishList\u003e usersWithWishLists() {\n        OneToMany\u003cUser, WishList\u003e wishListsPerUser = lightAccess.executeQuery((conn -\u003e \n                conn.prepareStatement(SELECT_WISHLISTS_PER_USER_SQL)\n                     .executeQuery()\n                     .normaliseOneToMany(this::mapToUserWishList)))\n        \n        return wishListsPerUser.collect((user, wishLists) -\u003e new UserWithWishList(user, wishLists));\n    }\n    \n    private KeyValue\u003cUser, Optional\u003cWishList\u003e\u003e mapToUserWishList(LAResultSet laResultSet) {\n        User user = new User(laResultSet.getInt(1), laResultSet.getString(2));\n\n        Optional\u003cWishList\u003e wishList = Optional.ofNullable((laResultSet.getInt(3) \u003e 0)\n                                                    ? new WishList(laResultSet.getInt(3),\n                                                                    laResultSet.getInt(4),\n                                                                    laResultSet.getString(5),\n                                                                    laResultSet.getLocalDate(6))\n                                                    : null);\n        return new KeyValue\u003c\u003e(user, wishList);\n    }    \n```\n\nFor more details, please check the [integration tests for joins][5]\n\n\u003ca name=\"insert\"\u003e\u003c/a\u003e\n### Insert\n\nLet's assume we have the following product table:\n\n```sql\nCREATE TABLE products (id VARCHAR(255) PRIMARY KEY, name VARCHAR(255), date TIMESTAMP)\n```\n\nAnd we have the following Product DTO. \n\n```java\n    public class Product {\n        private int id;\n        private String name;\n        private LocalDate date;\n    \n        public Product(int id, String name, LocalDate date) {\n            this.id = id;\n            this.name = name;\n            this.date = date;\n        }\n    \n        public int id() {\n            return id;\n        }\n    \n        public String name() {\n            return name;\n        }\n    \n        public LocalDate date() {\n            return date;\n        }\n        \n        // equals, hashcode\n    }\n```\n\nFor inserting a product, we just need to do the following:\n\n```java\n    INSERT_PRODUCT_SQL = \"insert into products (id, name, date) values (?, ?, ?)\";\n\n    Product product = new Product(1, \"Product 1\", LocalDate.of(2017, 07, 26));\n\n    lightAccess.executeCommand(conn -\u003e conn.prepareStatement(INSERT_PRODUCT_SQL)\n                                            .withParam(product.id())\n                                            .withParam(product.name())\n                                            .withParam(product.date())\n                                            .executeUpdate());\n```\n\nAnd as always, can extract the lambda to a method:\n\n```java\n    private SQLCommand insert(Product product) {\n        return conn -\u003e conn.prepareStatement(INSERT_PRODUCT_SQL)\n                            .withParam(product.id())\n                            .withParam(product.name())\n                            .withParam(product.date())\n                            .executeUpdate();\n    }\n```\n\nAnd call it like that:\n\n```java\n    lightAccess.executeCommand(insert(produt));\n```\n \n\u003ca name=\"update\"\u003e\u003c/a\u003e \n### Update \n\nLet's say that we wan to update the name of the given product.\n\n```java\nprivate static final String UPDATE_PRODUCT_NAME_SQL = \"update products set name = ? where id = ?\";\n```\n\nNow we can execute the update:\n\n```java\n    lightAccess.executeCommand(updateProductName(1, \"Another name\"));\n```\n\n```java\n    private SQLCommand updateProductName(int id, String name) {\n        return conn -\u003e conn.prepareStatement(UPDATE_PRODUCT_NAME_SQL)\n                            .withParam(name)\n                            .withParam(id)\n                            .executeUpdate();\n    }\n```\n\n\u003ca name=\"delete\"\u003e\u003c/a\u003e\n### Delete\n\nDelete is exactly the same as inserts and updates. \n\n## Calling sequences (PostgreSQL / H2)\n\nLet's first create a sequence:\n\n```java\n    private static final String ID_SEQUENCE = \"id_sequence\";\n    private static final String CREATE_SEQUENCE_DDL = \"CREATE SEQUENCE \" + ID_SEQUENCE + \" START WITH 1\";\n```\n\n```java\n    lightAccess.executeDDLCommand((conn) -\u003e conn.statement(CREATE_SEQUENCE_DDL).execute());\n```\n\nNow we can read the next ID from it. \n\n```java\n   int id = lightAccess.nextId(ID_SEQUENCE);\n```\n\nIn case we don't want an int ID, we can also map the ID to something else:\n\n```java\n    ProductID secondId = lightAccess.nextId(ID_SEQUENCE, ProductID::new);\n```\n\nWhere `ProductID` is:\n\n```java\n    public class ProductID {\n        private int id;\n    \n        public ProductID(int id) {\n            this.id = id;\n        }\n        \n        // getter, equals, hashcode\n    }\n```\n\nWe can also map that to String or any other object:\n\n```java\n    String stringID = lightAccess.nextId(ID_SEQUENCE, Object::toString);\n```\n\n\u003ca name=\"jdbcstatements\"\u003e\u003c/a\u003e\n### Creating Statement, PreparedStatement and CallableStatement\n\nAn instance of `LAConnection` will be received in all queries and commands represented by `DDLCommand`, `SQLCommand` \nand `SQLQuery`.  With this instance you can create a [Statement][6], [PreparedStatement][7] and [CallableStatement][8], \naccording to your need. \n\nAs a guideline, we normally use a `Statement` for DDL, a `PreparedStatement` for DML and `CallableStatement` for calling\nstored procedures or sequences. \n\n\u003ca name=\"furtherdocumentation\"\u003e\u003c/a\u003e\n# Further documentation \n\nPlease check the [tests][9] for more details in how to use this library.  \n\n\u003ca name=\"databases\"\u003e\u003c/a\u003e\n### Databases tested\n\nWe have only tested this library with [Amazon RDS][10] for [PostgreSQL][11]. \n\n\u003ca name=\"history\"\u003e\u003c/a\u003e\n## History\n\nThis library was first created by [Sandro Mancuso][12] while refactoring and removing duplication from multiple \nrepositories in one of the [Codurance][13]'s internal projects.\n\n[1]: https://docs.oracle.com/javase/tutorial/jdbc/basics/\n[2]: https://github.com/codurance/light-access/blob/master/src/main/java/com/codurance/lightaccess/LightAccess.java  \n[3]: https://martinfowler.com/eaaCatalog/repository.html\n[4]: http://www.h2database.com/html/main.html \n[5]: https://github.com/codurance/light-access/blob/master/src/test/java/integration/JoinsIntegrationTest.java\n[6]: https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html\n[7]: https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html\n[8]: https://docs.oracle.com/javase/8/docs/api/java/sql/CallableStatement.html\n[9]: https://github.com/codurance/light-access/tree/master/src/test/java\n[10]: https://aws.amazon.com/rds/\n[11]: https://www.postgresql.org/\n[12]: http://twitter.com/sandromancuso\n[13]: http://codurance.com","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodurance%2Flight-access","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodurance%2Flight-access","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodurance%2Flight-access/lists"}