HikariCPの概要
1. 概要
この紹介記事では、HikariCP JDBC接続プールプロジェクトについて学習します。 This is a very lightweight (at roughly 130Kb) and lightning fast JDBC connection pooling frameworkは、2012年頃にBrett Wooldridgeによって開発されました。
2. 前書き
HikariCPのパフォーマンスを、c3p0、dbcp2、tomcat、viburなどの他の接続プールフレームワークと比較するために利用できるベンチマーク結果がいくつかあります。 たとえば、HikariCPチームは以下のベンチマークを公開しました(元の結果はhereで利用可能):
次の手法が適用されているため、フレームワークは非常に高速です。
-
Bytecode-level engineering –いくつかの極端なバイトコードレベルのエンジニアリング(アセンブリレベルのネイティブコーディングを含む)が実行されました
-
Micro-optimizations –はほとんど測定できませんが、これらの最適化を組み合わせると、全体的なパフォーマンスが向上します
-
Intelligent use of the Collections framework –ArrayList<Statement>は、範囲チェックを排除し、テールからヘッドへの除去スキャンを実行するカスタムクラスFastListに置き換えられました。
3. メーベン依存
サンプルアプリケーションを作成して、その使用法を強調しましょう。 HikariCPは、JVMのすべての主要バージョンをサポートしています。 各バージョンには依存関係が必要です。 Java 9の場合:
com.zaxxer
HikariCP-java9ea
2.6.1
Java 8の場合:
com.zaxxer
HikariCP
2.6.1
6や7などの古いJDKバージョンもサポートされています。 適切なバージョンは、hereおよびhereにあります。 また、Central Maven Repositoryで最新バージョンを確認できます。
4. 使用法
それでは、デモアプリケーションを作成しましょう。 pom.xmlに適切なJDBCドライバークラスの依存関係を含める必要があることに注意してください。 依存関係が指定されていない場合、アプリケーションはClassNotFoundExceptionをスローします。
4.1. DataSourceの作成
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();
}
}
ここで注意すべき点は、staticブロックでの初期化です。
HikariConfigは、データソースを初期化するために使用される構成クラスです。 これには、4つのよく知られた必須パラメーターusername、password、jdbcUrl、dataSourceClassNameが付属しています。
jdbcUrlとdataSourceClassNameのうち、どちらか一方を同時に使用します。 ただし、このプロパティを古いドライバーで使用する場合は、両方のプロパティを設定する必要があります。
これらのプロパティに加えて、他のプーリングフレームワークによって提供されない可能性のある他のプロパティがいくつかあります。
-
autoCommit
-
connectionTimeout
-
idleTimeout
-
maxLifetime
-
connectionTestQuery
-
connectionInitSql
-
validateTimeout
-
maximumPoolSize
-
poolName
-
allowPoolSuspension
-
readOnly
-
transactionIsolation
-
LeakDetectionThreshold
これらのデータベースプロパティにより、HikariCPは際立っています。 接続リークを単独で検出するのに十分なほど高度です。
これらのプロパティの詳細な説明は、hereにあります。
resourcesディレクトリに配置されたプロパティファイルを使用して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という名前の2つのテーブルがあるとします。 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パラメータが付属しています。 JDBC URLは次のようになります。
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'
データベースからこれらのデータを取得するメソッドを作成する必要があります。
public static List fetchData() throws SQLException {
String SQL_QUERY = "select * from emp";
List 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を使用する利点とその構成について学習しました。
いつものように、完全なソースコードはover on GitHubで利用できます。