Рубрики
Без рубрики

Объединение пулов соединений в Java

Пул соединений означает пул объектов подключения. Объединение пулов соединений основано на шаблоне проектирования пула объектов. Используется шаблон проектирования объединения объектов

Автор оригинала: Pankaj Kumar.

Пул соединений означает пул объектов подключения. Объединение пулов соединений основано на шаблоне проектирования пула объектов. Шаблон проектирования объединения объектов используется, когда затраты (время и ресурсы, такие как процессор, сеть и ввод-вывод) на создание новых объектов выше. В соответствии с шаблоном проектирования объединения объектов приложение заранее создает объект и помещает его в пул или контейнер. Всякий раз, когда нашему приложению требуются такие объекты, оно получает их из пула, а не создает новый.

Приложение, использующее стратегию объединения соединений, уже имеет объекты подключения к БД, которые можно использовать повторно. Таким образом, когда возникает необходимость взаимодействия с базой данных, приложение получает экземпляры соединений из пула. Объединение пулов соединений повышает производительность приложений, взаимодействующих с базой данных.

Мы можем создать ваши собственные реализации объединения соединений. Любая структура пула соединений должна выполнять три задачи.

  • Создание Объектов Подключения
  • Управляйте использованием созданных объектов и проверяйте их
  • Освобождайте/Уничтожайте Объекты

С Java у нас есть отличный набор библиотек, которые легко доступны. Нам нужно настроить только несколько свойств, чтобы использовать их.

Объединение пулов соединений в Java-приложении

Давайте взглянем на нижеприведенные библиотеки:

  • Apache Commons DBCP2
  • ХикариКП
  • C3P0

Давайте рассмотрим приведенные ниже примеры из них один за другим. Для демонстрационных целей мы будем использовать базу данных MySQL и среду разработки Eclipse. Мы также создадим простой Java-проект на основе maven с использованием JDK 1.8.

Сценарии базы данных

create database empdb;

use empdb;

create table tblemployee(
                    empId integer AUTO_INCREMENT primary key,
                    empName varchar(64),
                    dob date,
                    designation varchar(64)
);

insert into  tblemployee(empId,empName,dob,designation) values (default,'Adam','1998-08-15','Manager');
insert into  tblemployee(empId,empName,dob,designation) values (default,'Smith','2001-01-11','Clerk');
insert into  tblemployee(empId,empName,dob,designation) values (default,'James','1996-03-13','Officer');

Пример Проекта

Выполните следующие действия, чтобы создать новый проект.

1) Откройте среду разработки Eclipse.

2) Нажмите меню Файл и выберите создать -> Проект Maven

3) Отобразится экран ниже. Выберите опцию создать простой проект и нажмите кнопку Далее.

4) Введите любой идентификатор группы, идентификатор артефакта, Имя и описание.

Нажмите Кнопку Готово.

5) Добавьте следующую зависимость в свой pom.xml для MySQL.


	mysql
	mysql-connector-java
	5.1.49

6) Щелкните правой кнопкой мыши на проекте, выберите Maven -> Обновить проект -> Ок. Он загрузит все зависимости.

1) Apache commons DBCP2

DBCP – это общий проект Apache. Для DBCP 2.7 требуется Java 8. Чтобы использовать DBCP 2, вам необходимо добавить в свой проект следующую зависимость.


	org.apache.commons
	commons-dbcp2
	2.7.0

Apache DBCP 2.0 предоставляет два типа источников данных (BasicDataSource и PoolingDataSource).

BasicDataSource: Как следует из названия, он прост и подходит для большинства распространенных случаев использования. Это внутренне создает для нас PoolingDataSource.

Давайте рассмотрим приведенные ниже шаги по инициализации пула соединений.

  1. Создайте экземпляр BasicDataSource
  2. Укажите URL-адрес JDBC, имя пользователя и пароль базы данных
  3. Укажите минимальное количество неработающих подключений ( минимальное количество подключений, которое должно оставаться в пуле в любое время).
  4. Укажите максимальное количество неработающих подключений (Максимальное количество неработающих подключений в пуле).
  5. Укажите общее максимальное количество подключений.
package com.journaldev.example;

/**
 * Java JDBC Connection pool using Apache commons DBCP2 example program
 * 
 * @author pankaj
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.commons.dbcp2.BasicDataSource;

public class DBCP2Demo {

	private static BasicDataSource dataSource = null;

	static {
		dataSource = new BasicDataSource();
		dataSource.setUrl("jdbc:mysql://localhost:3306/empdb?useSSL=false");
		dataSource.setUsername("root");
		dataSource.setPassword("root");

		dataSource.setMinIdle(5);
		dataSource.setMaxIdle(10);
		dataSource.setMaxTotal(25);

	}

public static void main(String[] args) throws SQLException {
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		try {
			connection = dataSource.getConnection();
			statement = connection.createStatement();
			resultSet = statement.executeQuery("select * from tblemployee");
			while (resultSet.next()) {
				System.out.println("empId:" + resultSet.getInt("empId"));
				System.out.println("empName:" + resultSet.getString("empName"));
				System.out.println("dob:" + resultSet.getDate("dob"));
				System.out.println("designation:" + resultSet.getString("designation"));
			}
		} finally {

			resultSet.close();
			statement.close();
			connection.close();
		}
	}

}

Выход:

empId:1
empName:Adam
dob:1998-08-15
designation:Manager
empId:2
empName:Smith
dob:2001-01-11
designation:Clerk
empId:3
empName:James
dob:1996-03-13
designation:Officer

PoolingDataSource: Он обеспечивает большую гибкость. Вам нужно только изменить код, который создает источник данных. Остальная часть кода останется прежней.

Давайте рассмотрим следующие шаги для инициализации пула соединений:

  1. Создайте экземпляр ConnectionFactory, используя URL-адрес JDBC.
  2. Создайте экземпляр PoolableConnectionFactory, используя экземпляр ConnectionFactory, который был создан на шаге 1
  3. Создайте экземпляр GenericObjectPoolConfig и задайте свойства максимального простоя, минимального простоя и максимального подключения
  4. Теперь инициализируйте пул объектов, используя экземпляры, созданные на шаге 2 и шаге 3
  5. Теперь установите пул в качестве экземпляра PoolableConnectionFactory
  6. Наконец, инициализируйте экземпляр источника данных
private static DataSource dataSource = null;

	static {

		Properties properties = new Properties();
		properties.setProperty("user", "root");
		properties.setProperty("password", "root");

		ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/empdb",
				properties);

		PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);

		GenericObjectPoolConfig config = new GenericObjectPoolConfig<>();
		config.setMaxTotal(25);
		config.setMaxIdle(10);
		config.setMinIdle(5);

		ObjectPool connectionPool = new GenericObjectPool<>(poolableConnectionFactory, config);
		poolableConnectionFactory.setPool(connectionPool);

		dataSource = new PoolingDataSource<>(connectionPool);

	}

2) ХикариКП

HikariCP быстр, надежен и прост. Это одно из предпочтительных решений для объединения соединений в пул. Фреймворки, такие как Spring Boot 2.x, используют его в качестве диспетчера соединений по умолчанию.

Чтобы использовать HikariCP, добавьте следующую зависимость в pom.xml вашего проекта.


	com.zaxxer
	HikariCP
	3.4.5

Конфигурация HikariCP :

Мы можем использовать конфигурацию на основе Java, как показано в приведенном ниже примере программы, или мы можем использовать файл свойств для настройки HikariCP. Давайте взглянем на приведенные ниже свойства.

  • время ожидания простоя : Время в миллисекундах, в течение которого объект подключения может оставаться в пуле в режиме ожидания. Он работает с минимальным временем простоя и Максимальным размером пула свойствами. По истечении указанного времени объект подключения будет освобожден.
  • время ожидания подключения : Время в миллисекундах, в течение которого клиент будет ждать объект подключения из пула. Если ограничение по времени будет достигнуто, то будет выдано исключение SQLException.
  • autoCommit : Мы можем указать значение true или false, и если оно равно true, то оно автоматически фиксирует все выполняемые вами операторы SQL, а если оно равно false, то нам нужно фиксировать операторы SQL вручную
  • cachePrepStmts: Включить кэширование для инструкции Prepare
  • минимальное время простоя: Минимальное количество объектов подключения должно оставаться в пуле в любое время.
  • Максимальный размер пула : Максимальное количество подключений, которые могут оставаться в пуле.
package com.journaldev.example;

/**
 * Java JDBC Connection pool using HikariCP example program
 * 
 * @author pankaj
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class HikariCPDemo {

	private static HikariDataSource dataSource = null;

	static {
		HikariConfig config = new HikariConfig();
		config.setJdbcUrl("jdbc:mysql://localhost:3306/empdb");
		config.setUsername("root");
		config.setPassword("root");
		config.addDataSourceProperty("minimumIdle", "5");
		config.addDataSourceProperty("maximumPoolSize", "25");

		dataSource = new HikariDataSource(config);
	}

	public static void main(String[] args) throws SQLException {
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		try {
			connection = dataSource.getConnection();
			statement = connection.createStatement();
			resultSet = statement.executeQuery("select * from tblemployee");
			while (resultSet.next()) {
				System.out.println("empId:" + resultSet.getInt("empId"));
				System.out.println("empName:" + resultSet.getString("empName"));
				System.out.println("dob:" + resultSet.getDate("dob"));
				System.out.println("designation:" + resultSet.getString("designation"));
			}
		} finally {
			resultSet.close();
			statement.close();
			connection.close();
		}
	}
}

Выход:

empId:1
empName:Adam
dob:1998-08-15
designation:Manager
empId:2
empName:Smith
dob:2001-01-11
designation:Clerk
empId:3
empName:James
dob:1996-03-13
designation:Officer

3) C3P0

C3P0-одна из старейших библиотек. Как правило, он используется с Hibernate. Чтобы использовать C3P0, нам нужно добавить в проект следующую зависимость.


	com.mchange
	c3p0
	0.9.5.5

Мы можем настроить следующие свойства с помощью C3P0.

  • класс драйвера : Предпочтительный Драйвер Jdbc
  • jdbcUrl : Url-адрес JDBC для базы данных.
  • Размер начального пула: количество подключений, созданных в пуле при запуске.
  • Приобретение: необходимо создать количество новых подключений, если текущего размера недостаточно.
  • Максимальное время : Количество секунд, в течение которых соединение может оставаться в пуле без использования.
  • maxPoolSize : Максимальное количество подключений, которые могут оставаться в пуле.
  • минимальный размер пула: Минимальное количество объектов подключения должно оставаться в пуле в любое время.
package com.journaldev.example;

/**
 * Java JDBC Connection pool using C3PO example program
 * 
 * @author pankaj
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo {

	static ComboPooledDataSource comboPooledDataSource = null;

	static {
		comboPooledDataSource = new ComboPooledDataSource();

		comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/empdb?useSSL=false");
		comboPooledDataSource.setUser("root");
		comboPooledDataSource.setPassword("root");

		comboPooledDataSource.setMinPoolSize(3);
		comboPooledDataSource.setAcquireIncrement(3);
		comboPooledDataSource.setMaxPoolSize(30);

	}

public static void main(String[] args) throws SQLException {
		Connection connection = null;
		Statement statement = null;
		ResultSet resultSet = null;
		try {
			connection = comboPooledDataSource.getConnection();
			statement = connection.createStatement();
			resultSet = statement.executeQuery("select * from tblemployee");
			while (resultSet.next()) {
				System.out.println("empId:" + resultSet.getInt("empId"));
				System.out.println("empName:" + resultSet.getString("empName"));
				System.out.println("dob:" + resultSet.getDate("dob"));
				System.out.println("designation:" + resultSet.getString("designation"));
			}
		} finally {
			resultSet.close();
			statement.close();
			connection.close();
		}
	}

}

Выход:

Aug 29, 2020 8:59:05 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge9kqacgbp7hjpftse6|77a567e1, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> null, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge9kqacgbp7hjpftse6|77a567e1, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/empdb?useSSL=false, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 30, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]

empId:1
empName:Adam
dob:1998-08-15
designation:Manager
empId:2
empName:Smith
dob:2001-01-11
designation:Clerk
empId:3
empName:James
dob:1996-03-13
designation:Officer

Это все для примера руководства по пулу соединений JDBC, я надеюсь, что здесь не было пропущено ничего важного.

Ссылки : HikariCP , Apache Commons DBCP , C3P0