diff --git a/persistence-modules/java-jdbi/README.md b/persistence-modules/java-jdbi/README.md
new file mode 100644
index 0000000000..3bab6faa29
--- /dev/null
+++ b/persistence-modules/java-jdbi/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Guide to CockroachDB in Java](http://www.baeldung.com/cockroachdb-java)
diff --git a/persistence-modules/java-jdbi/pom.xml b/persistence-modules/java-jdbi/pom.xml
new file mode 100644
index 0000000000..392f0bdcbf
--- /dev/null
+++ b/persistence-modules/java-jdbi/pom.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+ 4.0.0
+
+ java-jdbi
+ 1.0-SNAPSHOT
+
+
+
+ org.jdbi
+ jdbi3-core
+ 3.1.0
+
+
+ org.hsqldb
+ hsqldb
+ 2.4.0
+ test
+
+
+
+
+
+ Central
+ Central
+ http://repo1.maven.org/maven2/
+ default
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-jdbi/src/test/java/com/baeldung/persistence/jdbi/JdbiTest.java b/persistence-modules/java-jdbi/src/test/java/com/baeldung/persistence/jdbi/JdbiTest.java
new file mode 100644
index 0000000000..503bf90fdb
--- /dev/null
+++ b/persistence-modules/java-jdbi/src/test/java/com/baeldung/persistence/jdbi/JdbiTest.java
@@ -0,0 +1,338 @@
+package com.baeldung.persistence.jdbi;
+
+import org.jdbi.v3.core.Handle;
+import org.jdbi.v3.core.Jdbi;
+import org.jdbi.v3.core.result.ResultBearing;
+import org.jdbi.v3.core.result.ResultProducer;
+import org.jdbi.v3.core.statement.Query;
+import org.jdbi.v3.core.statement.StatementContext;
+import org.jdbi.v3.core.statement.Update;
+import org.junit.Test;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.*;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.*;
+
+public class JdbiTest {
+
+ @Test
+ public void whenJdbiCreated_thenSuccess() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+
+ Jdbi.create("WRONG");
+ }
+
+ @Test
+ public void whenJdbiWithProperties_thenSuccess() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+ jdbi.open().close();
+ Properties properties = new Properties();
+ properties.setProperty("username", "sa");
+ properties.setProperty("password", "");
+ jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", properties);
+ jdbi.open().close();
+ }
+
+ @Test
+ public void whenHandle_thenBoh() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+ final Handle[] handleRef = new Handle[1];
+ boolean closed = jdbi.withHandle(handle -> {
+ handleRef[0] = handle;
+ return handle.isClosed();
+ });
+
+ assertFalse(closed);
+ assertTrue(handleRef[0].isClosed());
+ }
+
+ @Test
+ public void whenTableCreated_thenInsertIsPossible() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+ jdbi.useHandle(handle -> {
+ int updateCount = handle.execute("create table PROJECT_1 (id integer identity, name varchar(50), url varchar(100))");
+
+ assertEquals(0, updateCount);
+
+ updateCount = handle.execute("INSERT INTO PROJECT_1 VALUES (1, 'tutorials', 'github.com/eugenp/tutorials')");
+
+ assertEquals(1, updateCount);
+ });
+ }
+
+ @Test
+ public void whenIdentityColumn_thenInsertReturnsNewId() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+ jdbi.useHandle(handle -> {
+ handle.execute("create table PROJECT_2 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))");
+ Update update = handle.createUpdate(
+ "INSERT INTO PROJECT_2 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')");
+ ResultBearing generatedKeys = update.executeAndReturnGeneratedKeys();
+
+ assertEquals(0, generatedKeys.mapToMap().findOnly().get("id"));
+
+ update = handle.createUpdate(
+ "INSERT INTO PROJECT_2 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')");
+
+ assertEquals(1, generatedKeys.mapToMap().findOnly().get("id"));
+ });
+ }
+
+ @Test
+ public void whenSelectMapToMap_thenResultsAreMapEntries() {
+ Jdbi jdbi = Jdbi.create("jdbc:hsqldb:mem:testDB", "sa", "");
+ jdbi.useHandle(handle -> {
+ handle.execute("create table PROJECT_3 (ID IDENTITY, NAME VARCHAR (50), URL VARCHAR (100))");
+ handle.execute("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('tutorials', 'github.com/eugenp/tutorials')");
+ handle.execute("INSERT INTO PROJECT_3 (NAME, URL) VALUES ('REST with Spring', 'github.com/eugenp/REST-With-Spring')");
+ Query query = handle.createQuery("select * from PROJECT_3 order by id");
+ List