Einführung in HikariCP

Einführung in HikariCP

1. Überblick

In diesem Einführungsartikel erfahren Sie mehr über das Verbindungspoolprojekt vonHikariCP JDBC. This is a very lightweight (at roughly 130Kb) and lightning fast JDBC connection pooling framework entwickelten sich um 2012 umBrett Wooldridge.

2. Einführung

Es stehen verschiedene Benchmark-Ergebnisse zur Verfügung, um die Leistung von HikariCP mit anderen Frameworks für Verbindungspools zu vergleichen, z. B.c3p0,dbcp2,tomcat undvibur. Zum Beispiel veröffentlichte das HikariCP-Team unter den Benchmarks (ursprüngliche Ergebnisse verfügbarhere):

image

Das Framework ist so schnell, weil die folgenden Techniken angewendet wurden:

  • Bytecode-level engineering – Es wurde ein Engineering auf extremer Bytecode-Ebene (einschließlich nativer Codierung auf Assembly-Ebene) durchgeführt

  • Micro-optimizations – Obwohl kaum messbar, steigern diese Optimierungen zusammen die Gesamtleistung

  • Intelligent use of the Collections framework –ArrayList<Statement> wurde durch eine benutzerdefinierte KlasseFastList ersetzt, die die Bereichsprüfung eliminiert und Entfernungsscans vom Schwanz zum Kopf durchführt

3. Maven-Abhängigkeit

Erstellen wir eine Beispielanwendung, um deren Verwendung hervorzuheben. HikariCP unterstützt alle Hauptversionen von JVM. Jede Version benötigt ihre Abhängigkeit; Für Java 9 haben wir:


    com.zaxxer
    HikariCP-java9ea
    2.6.1

Und für Java 8:


    com.zaxxer
    HikariCP
    2.6.1

Ältere JDK-Versionen wie 6 und 7 werden ebenfalls unterstützt. Die entsprechenden Versionen finden Sie unterhere undhere. Außerdem können wir die neuesten Versionen inCentral Maven Repository überprüfen.

4. Verwendungszweck

Jetzt erstellen wir eine Demo-Anwendung. Bitte beachten Sie, dass wir eine geeignete JDBC-Treiberklassenabhängigkeit inpom.xml aufnehmen müssen. Wenn keine Abhängigkeiten angegeben sind, gibt die AnwendungClassNotFoundException aus.

4.1. DataSource erstellen

Wir werdenDataSourcevon HikariCP verwenden, um eine einzelne Instanz einer Datenquelle für unsere Anwendung zu erstellen:

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

Hier ist die Initialisierung imstatic-Block zu beachten.

HikariConfig ist die Konfigurationsklasse, die zum Initialisieren einer Datenquelle verwendet wird. Es enthält vier bekannte Parameter, die unbedingt verwendet werden müssen:username,password,jdbcUrl,dataSourceClassName.

VonjdbcUrl unddataSourceClassName ist jeweils eines zu verwenden. Wenn Sie diese Eigenschaft jedoch mit älteren Treibern verwenden, müssen Sie möglicherweise beide Eigenschaften festlegen.

Zusätzlich zu diesen Eigenschaften sind verschiedene andere Eigenschaften verfügbar, die möglicherweise nicht alle von anderen Pooling-Frameworks angeboten werden:

  • autoCommit

  • Verbindungszeitüberschreitung

  • idleTimeout

  • maxLifetime

  • connectionTestQuery

  • connectionInitSql

  • validationTimeout

  • MaximumPoolSize

  • poolName

  • allowPoolSuspension

  • schreibgeschützt

  • transactionIsolation

  • leakDetectionThreshold

HikariCP zeichnet sich durch diese Datenbankeigenschaften aus. Es ist weit genug fortgeschritten, um sogar Verbindungslecks selbst zu erkennen!

Eine detaillierte Beschreibung dieser Eigenschaften finden Sie inhere.

Wir könnenHikariConfig auch mit einer Eigenschaftendatei initialisieren, die im Verzeichnisresources abgelegt ist:

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

Die Eigenschaftendatei sollte ungefähr so ​​aussehen:

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

Wir können auch diejava.util.Properties--basierte Konfiguration verwenden:

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

Alternativ können wir eine Datenquelle direkt initialisieren:

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

4.2. Verwenden einer Datenquelle

Nachdem wir die Datenquelle definiert haben, können wir sie verwenden, um eine Verbindung aus dem konfigurierten Verbindungspool abzurufen und JDBC-bezogene Aktionen auszuführen.

Angenommen, wir haben zwei Tabellen mit den Namendept undemp, um einen Anwendungsfall für Mitarbeiterabteilungen zu simulieren. Wir werden eine Klasse schreiben, um diese Details mit HikariCP aus der Datenbank abzurufen.

Im Folgenden sind die SQL-Anweisungen aufgeführt, die zum Erstellen der Beispieldaten erforderlich sind:

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

Bitte beachten Sie, dass bei Verwendung einer speicherinternen Datenbank wie H2 das Datenbankskript automatisch geladen werden muss, bevor der eigentliche Code zum Abrufen der Daten ausgeführt wird. Zum Glück enthält H2 einenINIT-Parameter, mit dem das Datenbankskript zur Laufzeit aus dem Klassenpfad geladen werden kann. Die JDBC-URL sollte folgendermaßen aussehen:

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

Wir müssen eine Methode erstellen, um diese Daten aus der Datenbank abzurufen:

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

Jetzt müssen wir möglicherweise eine JUnit-Methode erstellen, um sie zu testen. Da wir die Anzahl der Zeilen in der Tabelleemp kennen, können wir erwarten, dass die Größe der zurückgegebenen Liste der Anzahl der Zeilen entspricht:

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

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

5. Fazit

In diesem kurzen Tutorial haben wir die Vorteile der Verwendung von HikariCP und seiner Konfiguration kennengelernt.

Wie immer ist der vollständige Quellcodeover on GitHub verfügbar.