Pengantar HikariCP

1. Ikhtisar

Dalam artikel pengantar ini, kita akan belajar tentang proyek kumpulan koneksi JDBC HikariCP. Ini adalah kerangka penyatuan koneksi JDBC yang sangat ringan (sekitar 130Kb) dan secepat kilat yang dikembangkan oleh Brett Wooldridge sekitar tahun 2012.

2. Pendahuluan

Ada beberapa hasil benchmark yang tersedia untuk membandingkan kinerja HikariCP dengan framework penyatuan koneksi lainnya seperti c3p0 , dbcp2 , tomcat , dan vibur . Misalnya, tim HikariCP yang diterbitkan di bawah tolok ukur (hasil asli tersedia di sini):

Kerangka kerjanya sangat cepat karena teknik berikut telah diterapkan:

  • Rekayasa tingkat kode byte - beberapa rekayasa tingkat kode byte ekstrim (termasuk pengkodean asli tingkat perakitan) telah dilakukan
  • Pengoptimalan mikro - meskipun hampir tidak dapat diukur, pengoptimalan ini digabungkan meningkatkan kinerja secara keseluruhan
  • Cerdas menggunakan kerangka Koleksi - yang ArrayList digantikan dengan kelas kustom daftar cepat yang menghilangkan rentang memeriksa dan penghapusan melakukan scan dari ekor ke kepala

3. Ketergantungan Maven

Mari buat aplikasi contoh untuk menyoroti penggunaannya. HikariCP hadir dengan dukungan untuk semua versi utama JVM. Setiap versi membutuhkan ketergantungannya; untuk Java 8 hingga 11, kami memiliki:

 com.zaxxer HikariCP 3.4.5 

Versi JDK yang lebih lama seperti 6 dan 7 juga didukung. Versi yang sesuai dapat ditemukan di sini dan di sini. Selain itu, kami dapat memeriksa versi terbaru di Central Maven Repository.

4. Penggunaan

Sekarang mari buat aplikasi demo. Harap dicatat bahwa kami perlu menyertakan dependensi kelas driver JDBC yang sesuai di pom.xml . Jika tidak ada dependensi yang disediakan, aplikasi akan menampilkan ClassNotFoundException .

4.1. Membuat Sumber Data

Kami akan menggunakan HikariCP ini DataSource untuk membuat satu contoh dari sumber data untuk aplikasi kita:

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(); } }

Poin yang perlu diperhatikan di sini adalah inisialisasi di blok statis .

HikariConfig adalah kelas konfigurasi yang digunakan untuk menginisialisasi sumber data. Muncul dengan empat parameter terkenal yang harus digunakan username , password , jdbcUrl , dataSourceClassName .

Dari jdbcUrl dan dataSourceClassName , salah satunya akan digunakan pada satu waktu. Namun, saat menggunakan properti ini dengan driver lama, kita mungkin perlu menyetel kedua properti tersebut.

Selain properti ini, ada beberapa properti lain yang tersedia yang mungkin tidak semuanya ditawarkan oleh framework penggabungan lainnya:

  • AutoCommit
  • waktu koneksi habis
  • idleTimeout
  • maxLifetime
  • connectionTestQuery
  • connectionInitSql
  • validationTimeout
  • maximumPoolSize
  • poolName
  • allowPoolSuspension
  • readOnly
  • transactionIsolation
  • kebocoranDetectionThreshold

HikariCP menonjol karena properti database ini. Ini cukup canggih bahkan untuk mendeteksi kebocoran koneksi dengan sendirinya!

Penjelasan rinci tentang properti ini dapat ditemukan di sini.

Kami juga dapat menginisialisasi HikariConfig dengan file properti yang ditempatkan di direktori sumber daya :

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

File properti akan terlihat seperti ini:

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

Kita juga dapat menggunakan konfigurasi berbasis 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 );

Alternatifnya, kita bisa menginisialisasi sumber data secara langsung:

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

4.2. Menggunakan Sumber Data

Sekarang kita telah menentukan sumber data, kita dapat menggunakannya untuk mendapatkan koneksi dari kumpulan koneksi yang dikonfigurasi dan melakukan tindakan terkait JDBC.

Misalkan kita memiliki dua tabel bernama dept dan emp untuk mensimulasikan kasus penggunaan departemen karyawan. Kami akan menulis kelas untuk mengambil detail tersebut dari database menggunakan HikariCP.

Di bawah ini kami mencantumkan pernyataan SQL yang diperlukan untuk membuat data sampel:

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 );

Harap diperhatikan jika kita menggunakan database dalam memori seperti H2, kita perlu memuat skrip database secara otomatis sebelum menjalankan kode sebenarnya untuk mengambil data. Untungnya, H2 hadir dengan parameter INIT yang dapat memuat skrip database dari classpath saat runtime. URL JDBC akan terlihat seperti ini:

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

Kita perlu membuat metode untuk mengambil data ini dari database:

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; }

Sekarang, kita perlu membuat metode JUnit untuk mengujinya. Karena kita mengetahui jumlah baris dalam emp tabel , kita dapat mengharapkan bahwa ukuran daftar yang dikembalikan harus sama dengan jumlah baris:

@Test public void givenConnection_thenFetchDbData() throws SQLException { HikariCPDemo.fetchData(); assertEquals( 4, employees.size() ); }

5. Kesimpulan

Dalam tutorial singkat ini, kita belajar tentang keuntungan menggunakan HikariCP dan konfigurasinya.

Seperti biasa, kode sumber lengkap tersedia di GitHub.