Introduction à HikariCP

Introduction à HikariCP

1. Vue d'ensemble

Dans cet article d’introduction, nous découvrirons le projet de pool de connexionsHikariCP JDBC. This is a very lightweight (at roughly 130Kb) and lightning fast JDBC connection pooling framework développé parBrett Wooldridge vers 2012.

2. introduction

Il existe plusieurs résultats de référence disponibles pour comparer les performances d'HikariCP avec d'autres cadres de regroupement de connexions tels quec3p0,dbcp2,tomcat etvibur. Par exemple, l'équipe HikariCP a publié ci-dessous les benchmarks (résultats originaux disponibleshere):

image

Le framework est tellement rapide car les techniques suivantes ont été appliquées:

  • Bytecode-level engineering – une certaine ingénierie extrême au niveau du bytecode (y compris le codage natif au niveau de l'assemblage) a été effectuée

  • Micro-optimizations – bien qu'à peine mesurables, ces optimisations combinées augmentent les performances globales

  • Intelligent use of the Collections framework – leArrayList<Statement> a été remplacé par une classe personnaliséeFastList qui élimine la vérification de portée et effectue des balayages de suppression de la queue à la tête

3. Dépendance Maven

Créons un exemple d'application pour mettre en évidence son utilisation. HikariCP prend en charge toutes les versions principales de la machine virtuelle Java. Chaque version nécessite sa dépendance; pour Java 9, nous avons:


    com.zaxxer
    HikariCP-java9ea
    2.6.1

Et pour Java 8:


    com.zaxxer
    HikariCP
    2.6.1

Les anciennes versions de JDK, telles que 6 et 7, sont également prises en charge. Les versions appropriées peuvent être trouvéeshere ethere. De plus, nous pouvons vérifier les dernières versions dans lesCentral Maven Repository.

4. Usage

Créons maintenant une application de démonstration. Veuillez noter que nous devons inclure une dépendance de classe de pilote JDBC appropriée dans lespom.xml. Si aucune dépendance n'est fournie, l'application lèvera unClassNotFoundException.

4.1. Créer unDataSource

Nous utiliserons lesDataSource de HikariCP pour créer une seule instance d'une source de données pour notre application:

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

Point à noter ici est l'initialisation dans le blocstatic.

HikariConfig est la classe de configuration utilisée pour initialiser une source de données. Il est livré avec quatre paramètres incontournables bien connususername,password,jdbcUrl,dataSourceClassName.

SurjdbcUrl etdataSourceClassName, l'un ou l'autre doit être utilisé à la fois. Toutefois, lorsque vous utilisez cette propriété avec des pilotes plus anciens, il peut être nécessaire de définir les deux propriétés.

En plus de ces propriétés, il existe plusieurs autres propriétés disponibles qui peuvent ne pas toutes être offertes par d'autres frameworks de mise en pool:

  • autoCommit

  • délai de connection dépassé

  • délai d'inactivité

  • maxLifetime

  • connectionTestQuery

  • connectionInitSql

  • validationTimeout

  • maximumPoolSize

  • poolName

  • allowPoolSuspension

  • lecture seulement

  • transactionIsolation

  • fuiteDetectionThreshold

HikariCP se distingue par ces propriétés de base de données. Il est suffisamment avancé pour même détecter les fuites de connexion par lui-même!

Une description détaillée de ces propriétés peut être trouvéehere.

On peut également initialiserHikariConfig avec un fichier de propriétés placé dans le répertoireresources:

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

Le fichier de propriétés devrait ressembler à ceci:

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

Nous pouvons également utiliser la configuration basée surjava.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 );

Alternativement, nous pouvons initialiser directement une source de données:

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

4.2. Utilisation d'une source de données

Maintenant que nous avons défini la source de données, nous pouvons l’utiliser pour obtenir une connexion à partir du pool de connexions configuré et effectuer des actions liées à JDBC.

Supposons que nous ayons deux tables nomméesdept etemp pour simuler un cas d'utilisation employé-service. Nous allons écrire une classe pour extraire ces détails de la base de données en utilisant HikariCP.

Ci-dessous, nous listons les instructions SQL nécessaires pour créer les exemples de données:

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

Veuillez noter que si nous utilisons une base de données en mémoire telle que H2, nous devons charger automatiquement le script de base de données avant d'exécuter le code pour extraire les données. Heureusement, H2 est livré avec un paramètreINIT qui peut charger le script de base de données à partir du chemin de classe au moment de l'exécution. L'URL JDBC devrait ressembler à:

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

Nous devons créer une méthode pour extraire ces données de la base de données:

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

Maintenant, nous pouvons avoir besoin de créer une méthode JUnit pour la tester. Puisque nous connaissons le nombre de lignes dans la tableemp, nous pouvons nous attendre à ce que la taille de la liste retournée soit égale au nombre de lignes:

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

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

5. Conclusion

Dans ce rapide tutoriel, nous avons appris les avantages de l’utilisation de HikariCP et de sa configuration.

Comme toujours, le code source complet est disponibleover on GitHub.