Перейти к основному содержимому

Введение в HikariCP

· 6 мин. чтения

Задача: Наибольшая подстрока без повторений

Для заданной строки s, найдите длину наибольшей подстроки без повторяющихся символов. Подстрока — это непрерывная непустая последовательность символов внутри строки...

ANDROMEDA 42

1. Обзор

В этом вводном руководстве мы узнаем о проекте пула соединений HikariCP JDBC . Это очень легкая (примерно 130 КБ) и молниеносная среда пула соединений JDBC, разработанная Бреттом Вулдриджем примерно в 2012 году.

2. Введение

Доступно несколько тестовых результатов для сравнения производительности HikariCP с другими платформами пула соединений, такими как c3p0 , dbcp2 , tomcat и vibur . Например, команда HikariCP опубликовала следующие бенчмарки (исходные результаты доступны здесь ):

./c4d024f89486914516d9722cc5f18528.png

Фреймворк такой быстрый, потому что были применены следующие методы:

  • Разработка на уровне байт-кода - была выполнена некоторая экстремальная разработка на уровне байт-кода (включая собственное кодирование на уровне сборки).
  • Микрооптимизации — хотя их едва можно измерить, в совокупности эти оптимизации повышают общую производительность.
  • Интеллектуальное использование платформы коллекций — ArrayList <Statement> был заменен настраиваемым классом FastList, который устраняет проверку диапазона и выполняет сканирование удаления от начала до конца.

3. Зависимость от Maven

Во-первых, давайте создадим пример приложения, чтобы выделить его использование. HikariCP поставляется с поддержкой всех основных версий JVM. Каждая версия требует своей зависимости. Для Java с 8 по 11 у нас есть:

<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>

HikariCP также поддерживает более старые версии JDK, вроде 6 и 7. Соответствующие версии можно найти здесь и здесь соответственно. Мы также можем проверить последние версии в Центральном репозитории Maven .

4. Использование

Теперь мы можем создать демонстрационное приложение. Обратите внимание, что нам нужно включить подходящую зависимость класса драйвера JDBC в pom.xml . Если зависимости не указаны, приложение выдаст исключение ClassNotFoundException .

4.1. Создание источника данных

Мы будем использовать HikariCP DataSource для создания одного экземпляра источника данных для нашего приложения:

public class DataSource {

private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;

static {
config.setJdbcUrl( "jdbc_url" );
config.setUsername( "database_username" );
config.setPassword( "database_password" );
config.addDataSourceProperty( "cachePrepStmts" , "true" );
config.addDataSourceProperty( "prepStmtCacheSize" , "250" );
config.addDataSourceProperty( "prepStmtCacheSqlLimit" , "2048" );
ds = new HikariDataSource( config );
}

private DataSource() {}

public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}

Здесь следует отметить один момент — инициализацию в статическом блоке.

HikariConfig — это класс конфигурации, используемый для инициализации источника данных. Он поставляется с четырьмя известными обязательными параметрами: имя пользователя , пароль , jdbcUrl и dataSourceClassName .

Из jdbcUrl и dataSourceClassName мы обычно используем по одному. Однако при использовании этого свойства со старыми драйверами нам может потребоваться установить оба свойства.

В дополнение к этим свойствам есть несколько других доступных свойств, которые мы можем не найти в других платформах объединения:

  • автофиксация
  • время соединения вышло
  • idleTimeout
  • maxLifetime
  • соединениеTestQuery
  • соединениеInitSql
  • валидациятаймаут
  • максимальный размер пула
  • имя_пула
  • allowPoolSuspension
  • только для чтения
  • изоляция транзакции
  • Порог обнаружения утечки

HikariCP выделяется из-за этих свойств базы данных. Он даже достаточно продвинут, чтобы самостоятельно обнаруживать утечки соединений.

Подробное описание вышеуказанных свойств можно найти здесь .

Мы также можем инициализировать HikariConfig с помощью файла свойств, расположенного в каталоге ресурсов :

private static HikariConfig config = new HikariConfig(
"datasource.properties" );

Файл свойств должен выглядеть примерно так:

dataSourceClassName= //TBD
dataSource.user= //TBD
//other properties name should start with dataSource as shown above

Кроме того, мы можем использовать конфигурацию на основе java.util.Properties :

Properties props = new Properties();
props.setProperty( "dataSourceClassName" , //TBD );
props.setProperty( "dataSource.user" , //TBD );
//setter for other required properties
private static HikariConfig config = new HikariConfig( props );

В качестве альтернативы мы можем инициализировать источник данных напрямую:

ds.setJdbcUrl( //TBD  );
ds.setUsername( //TBD );
ds.setPassword( //TBD );

4.2. Использование источника данных

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

Предположим, у нас есть две таблицы с именами dept и emp для имитации варианта использования «сотрудник-отдел». Мы напишем класс для извлечения этих деталей из базы данных с помощью HikariCP.

Ниже мы перечислим операторы SQL, необходимые для создания примера данных:

create table dept(
deptno numeric,
dname varchar(14),
loc varchar(13),
constraint pk_dept primary key ( deptno )
);

create table emp(
empno numeric,
ename varchar(10),
job varchar(9),
mgr numeric,
hiredate date,
sal numeric,
comm numeric,
deptno numeric,
constraint pk_emp primary key ( empno ),
constraint fk_deptno foreign key ( deptno ) references dept ( deptno )
);

insert into dept values( 10, 'ACCOUNTING', 'NEW YORK' );
insert into dept values( 20, 'RESEARCH', 'DALLAS' );
insert into dept values( 30, 'SALES', 'CHICAGO' );
insert into dept values( 40, 'OPERATIONS', 'BOSTON' );

insert into emp values(
7839, 'KING', 'PRESIDENT', null,
to_date( '17-11-1981' , 'dd-mm-yyyy' ),
7698, null, 10
);
insert into emp values(
7698, 'BLAKE', 'MANAGER', 7839,
to_date( '1-5-1981' , 'dd-mm-yyyy' ),
7782, null, 20
);
insert into emp values(
7782, 'CLARK', 'MANAGER', 7839,
to_date( '9-6-1981' , 'dd-mm-yyyy' ),
7566, null, 30
);
insert into emp values(
7566, 'JONES', 'MANAGER', 7839,
to_date( '2-4-1981' , 'dd-mm-yyyy' ),
7839, null, 40
);

Обратите внимание: если мы используем базу данных в памяти, такую как H2, нам необходимо автоматически загрузить сценарий базы данных перед запуском фактического кода для извлечения данных. К счастью, H2 поставляется с параметром INIT , который может загружать скрипт базы данных из пути к классам во время выполнения. URL-адрес JDBC должен выглядеть так:

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'

Нам нужно создать метод для извлечения этих данных из базы данных:

public static List<Employee> fetchData() throws SQLException {
String SQL_QUERY = "select * from emp";
List<Employee> employees = null;
try (Connection con = DataSource.getConnection();
PreparedStatement pst = con.prepareStatement( SQL_QUERY );
ResultSet rs = pst.executeQuery();) {
employees = new ArrayList<>();
Employee employee;
while ( rs.next() ) {
employee = new Employee();
employee.setEmpNo( rs.getInt( "empno" ) );
employee.setEname( rs.getString( "ename" ) );
employee.setJob( rs.getString( "job" ) );
employee.setMgr( rs.getInt( "mgr" ) );
employee.setHiredate( rs.getDate( "hiredate" ) );
employee.setSal( rs.getInt( "sal" ) );
employee.setComm( rs.getInt( "comm" ) );
employee.setDeptno( rs.getInt( "deptno" ) );
employees.add( employee );
}
}
return employees;
}

Затем нам нужно создать метод JUnit для его проверки. Поскольку мы знаем количество строк в таблице emp , мы можем ожидать, что размер возвращаемого списка должен быть равен количеству строк:

@Test
public void givenConnection_thenFetchDbData() throws SQLException {
HikariCPDemo.fetchData();

assertEquals( 4, employees.size() );
}

5. Вывод

В этой краткой статье мы узнали о преимуществах использования HikariCP и его настройке.

Как всегда, полный исходный код доступен на GitHub .