diff --git a/core-java/pom.xml b/core-java/pom.xml
index 6ead63cfab..c52b109f72 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -1,5 +1,5 @@
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.baeldung
core-java
@@ -73,9 +73,10 @@
org.assertj
assertj-core
- ${assertj.version}
+ ${assertj-core.version}
test
+
commons-codec
commons-codec
@@ -146,6 +147,21 @@
icu4j
${icu4j.version}
+
+ org.apache.commons
+ commons-dbcp2
+ ${commons-dbcp2.version}
+
+
+ com.zaxxer
+ HikariCP
+ ${HikariCP.version}
+
+
+ com.mchange
+ c3p0
+ ${c3p0.version}
+
@@ -301,7 +317,7 @@
-
+
org.apache.maven.plugins
maven-javadoc-plugin
@@ -348,6 +364,7 @@
org.codehaus.mojo
exec-maven-plugin
+ ${exec-maven-plugin.version}
run-benchmarks
@@ -375,6 +392,7 @@
+
2.8.5
2.8.2
@@ -395,16 +413,23 @@
0.9.0
- 3.6.1
+ 3.10.0
+
+ 2.4.0
+ 3.2.0
+ 0.9.5.2
+
2.19.1
4.3.4.RELEASE
1.5.8.RELEASE
+
1.1
1.4.197
2.1.0.1
1.19
+
1.19
3.0.0-M1
1.5.0-b01
@@ -412,7 +437,8 @@
1.4.4
3.1.1
2.0.3.RELEASE
+ 1.6.0
61.1
-
\ No newline at end of file
+
diff --git a/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/BasicConnectionPool.java b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/BasicConnectionPool.java
new file mode 100644
index 0000000000..243ec88eb5
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/BasicConnectionPool.java
@@ -0,0 +1,87 @@
+package com.baeldung.connectionpool.connectionpools;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BasicConnectionPool implements ConnectionPool {
+
+ private final String url;
+ private final String user;
+ private final String password;
+ private final List connectionPool;
+ private final List usedConnections = new ArrayList<>();
+ private static final int INITIAL_POOL_SIZE = 10;
+ private final int MAX_POOL_SIZE = 20;
+
+ public static BasicConnectionPool create(String url, String user, String password) throws SQLException {
+ List pool = new ArrayList<>(INITIAL_POOL_SIZE);
+ for (int i = 0; i < INITIAL_POOL_SIZE; i++) {
+ pool.add(createConnection(url, user, password));
+ }
+ return new BasicConnectionPool(url, user, password, pool);
+ }
+
+ private BasicConnectionPool(String url, String user, String password, List connectionPool) {
+ this.url = url;
+ this.user = user;
+ this.password = password;
+ this.connectionPool = connectionPool;
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ if (connectionPool.size() == 0) {
+ if (usedConnections.size() < MAX_POOL_SIZE) {
+ connectionPool.add(createConnection(url, user, password));
+ } else {
+ throw new RuntimeException("Maximum pool size reached, no available connections!");
+ }
+ }
+
+ Connection connection = connectionPool.remove(connectionPool.size() - 1);
+ usedConnections.add(connection);
+ return connection;
+ }
+
+ @Override
+ public boolean releaseConnection(Connection connection) {
+ connectionPool.add(connection);
+ return usedConnections.remove(connection);
+ }
+
+ private static Connection createConnection(String url, String user, String password) throws SQLException {
+ return DriverManager.getConnection(url, user, password);
+ }
+
+ public int getSize() {
+ return connectionPool.size() + usedConnections.size();
+ }
+
+ @Override
+ public String getUrl() {
+ return url;
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ public void shutdown() throws SQLException {
+ for (Connection c : usedConnections) {
+ this.releaseConnection(c);
+ }
+ for (Connection c : connectionPool) {
+ c.close();
+ }
+ connectionPool.clear();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/C3poDataSource.java b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/C3poDataSource.java
new file mode 100644
index 0000000000..5b91f707a9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/C3poDataSource.java
@@ -0,0 +1,28 @@
+package com.baeldung.connectionpool.connectionpools;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+import java.beans.PropertyVetoException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class C3poDataSource {
+
+ private static final ComboPooledDataSource cpds = new ComboPooledDataSource();
+
+ static {
+ try {
+ cpds.setDriverClass("org.h2.Driver");
+ cpds.setJdbcUrl("jdbc:h2:mem:test");
+ cpds.setUser("user");
+ cpds.setPassword("password");
+ } catch (PropertyVetoException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Connection getConnection() throws SQLException {
+ return cpds.getConnection();
+ }
+
+ private C3poDataSource(){}
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/ConnectionPool.java b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/ConnectionPool.java
new file mode 100644
index 0000000000..3d5ad06c3d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/ConnectionPool.java
@@ -0,0 +1,18 @@
+package com.baeldung.connectionpool.connectionpools;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+public interface ConnectionPool {
+
+ Connection getConnection() throws SQLException;
+
+ boolean releaseConnection(Connection connection);
+
+ String getUrl();
+
+ String getUser();
+
+ String getPassword();
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/DBCPDataSource.java b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/DBCPDataSource.java
new file mode 100644
index 0000000000..2f33cde883
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/DBCPDataSource.java
@@ -0,0 +1,25 @@
+package com.baeldung.connectionpool.connectionpools;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.apache.commons.dbcp2.BasicDataSource;
+
+public class DBCPDataSource {
+
+ private static final BasicDataSource ds = new BasicDataSource();
+
+ static {
+ ds.setUrl("jdbc:h2:mem:test");
+ ds.setUsername("user");
+ ds.setPassword("password");
+ ds.setMinIdle(5);
+ ds.setMaxIdle(10);
+ ds.setMaxOpenPreparedStatements(100);
+ }
+
+ public static Connection getConnection() throws SQLException {
+ return ds.getConnection();
+ }
+
+ private DBCPDataSource(){}
+}
diff --git a/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/HikariCPDataSource.java b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/HikariCPDataSource.java
new file mode 100644
index 0000000000..5ed2de181d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/connectionpool/connectionpools/HikariCPDataSource.java
@@ -0,0 +1,28 @@
+package com.baeldung.connectionpool.connectionpools;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class HikariCPDataSource {
+
+ private static final HikariConfig config = new HikariConfig();
+ private static final HikariDataSource ds;
+
+ static {
+ config.setJdbcUrl("jdbc:h2:mem:test");
+ config.setUsername("user");
+ config.setPassword("password");
+ config.addDataSourceProperty("cachePrepStmts", "true");
+ config.addDataSourceProperty("prepStmtCacheSize", "250");
+ config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+ ds = new HikariDataSource(config);
+ }
+
+ public static Connection getConnection() throws SQLException {
+ return ds.getConnection();
+ }
+
+ private HikariCPDataSource(){}
+}
diff --git a/core-java/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java b/core-java/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java
new file mode 100644
index 0000000000..5edc6bba94
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/connectionpool/BasicConnectionPoolUnitTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.connectionpool;
+
+import com.baeldung.connectionpool.connectionpools.BasicConnectionPool;
+import com.baeldung.connectionpool.connectionpools.ConnectionPool;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BasicConnectionPoolUnitTest {
+
+ private static ConnectionPool connectionPool;
+
+ @BeforeClass
+ public static void setUpBasicConnectionPoolInstance() throws SQLException {
+ connectionPool = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password");
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenCalledgetConnection_thenCorrect() throws Exception {
+ assertTrue(connectionPool.getConnection().isValid(1));
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenCalledreleaseConnection_thenCorrect() throws Exception {
+ Connection connection = connectionPool.getConnection();
+ assertThat(connectionPool.releaseConnection(connection)).isTrue();
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenCalledgetUrl_thenCorrect() {
+ assertThat(connectionPool.getUrl()).isEqualTo("jdbc:h2:mem:test");
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenCalledgetUser_thenCorrect() {
+ assertThat(connectionPool.getUser()).isEqualTo("user");
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenCalledgetPassword_thenCorrect() {
+ assertThat(connectionPool.getPassword()).isEqualTo("password");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void givenBasicConnectionPoolInstance_whenAskedForMoreThanMax_thenError() throws Exception {
+ // this test needs to be independent so it doesn't share the same connection pool as other tests
+ ConnectionPool cp = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password");
+ final int MAX_POOL_SIZE = 20;
+ for (int i = 0; i < MAX_POOL_SIZE + 1; i++) {
+ cp.getConnection();
+ }
+ fail();
+ }
+
+ @Test
+ public void givenBasicConnectionPoolInstance_whenSutdown_thenEmpty() throws Exception {
+ ConnectionPool cp = BasicConnectionPool.create("jdbc:h2:mem:test", "user", "password");
+ assertThat(((BasicConnectionPool)cp).getSize()).isEqualTo(10);
+
+ ((BasicConnectionPool) cp).shutdown();
+ assertThat(((BasicConnectionPool)cp).getSize()).isEqualTo(0);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java b/core-java/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java
new file mode 100644
index 0000000000..a02daa40f6
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/connectionpool/C3poDataSourceUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.connectionpool;
+
+import com.baeldung.connectionpool.connectionpools.C3poDataSource;
+import java.sql.SQLException;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class C3poDataSourceUnitTest {
+
+ @Test
+ public void givenC3poDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException {
+ assertTrue(C3poDataSource.getConnection().isValid(1));
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java b/core-java/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java
new file mode 100644
index 0000000000..9583eedf4b
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/connectionpool/DBCPDataSourceUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.connectionpool;
+
+import com.baeldung.connectionpool.connectionpools.DBCPDataSource;
+import java.sql.SQLException;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class DBCPDataSourceUnitTest {
+
+ @Test
+ public void givenDBCPDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException {
+ assertTrue(DBCPDataSource.getConnection().isValid(1));
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java b/core-java/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java
new file mode 100644
index 0000000000..6b78815797
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/connectionpool/HikariCPDataSourceUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.connectionpool;
+
+import com.baeldung.connectionpool.connectionpools.HikariCPDataSource;
+import java.sql.SQLException;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class HikariCPDataSourceUnitTest {
+
+ @Test
+ public void givenHikariDataSourceClass_whenCalledgetConnection_thenCorrect() throws SQLException {
+ assertTrue(HikariCPDataSource.getConnection().isValid(1));
+ }
+}
\ No newline at end of file