Traitement par lots dans JDBC

Traitement par lots dans JDBC

1. introduction

JDBC (Java Database Connectivity) est une API Java utilisée pour interagir avec des bases de données. Le traitement par lots regroupe plusieurs requêtes dans une unité et les transmet en une seule fois à une base de données.

Dans cet article, nous découvrirons comment JDBC peut être utilisé pour le traitement par lots des requêtes SQL.

Pour en savoir plus sur JDBC, vous pouvez consulter notre article d'introductionhere.

2. Pourquoi le traitement par lots?

La performance et la cohérence des données sont les principales motivations du traitement par lots.

2.1. Performance améliorée

Certains cas d'utilisation nécessitent l'insertion d'une grande quantité de données dans une table de base de données. Lors de l'utilisation de JDBC, l'un des moyens d'y parvenir sans traitement par lots consiste à exécuter plusieurs requêtes de manière séquentielle.

Voyons un exemple de requêtes séquentielles envoyées à la base de données:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')");
statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('2','EmployeeName2','Designation2')");

Ces appels séquentiels augmenteront le nombre de voyages réseau vers la base de données, ce qui entraînera de mauvaises performances.

En utilisant le traitement par lots, ces requêtes peuvent être envoyées à la base de données en un seul appel, améliorant ainsi les performances.

2.2. La cohérence des données

Dans certaines circonstances, les données doivent être placées dans plusieurs tables. Cela conduit à une transaction interdépendante dans laquelle la séquence de requêtes envoyées est importante.

Toute erreur survenant au cours de l'exécution devrait entraîner une éventuelle restauration des données transmises par les requêtes précédentes.

Voyons un exemple d’ajout de données à plusieurs tables:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')");
statement.execute("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");

Un problème typique de l'approche ci-dessus survient lorsque la première instruction réussit et que la seconde échoue. In this situation there is no rollback of the data inserted by the first statement, leading to data inconsistency.

Nous pouvons assurer la cohérence des données en couvrant une transaction sur plusieurs insertions / mises à jour, puis en validant la transaction à la fin ou en effectuant une annulation en cas d'exceptions, mais dans ce cas, nous continuons à accéder à la base de données à plusieurs reprises pour chaque instruction.

3. Comment effectuer un traitement par lots

JDBC fournit deux classes,Statement etPreparedStatement pour exécuter des requêtes sur la base de données. Les deux classes ont leur propre implémentation des méthodesaddBatch() etexecuteBatch() qui nous fournissent la fonctionnalité de traitement par lots.

3.1. Traitement par lots avecStatement

Avec JDBC, le moyen le plus simple d'exécuter des requêtes sur une base de données est via l'objetStatement.

Tout d'abord, en utilisantaddBatch(), nous pouvons ajouter toutes les requêtes SQL à un lot, puis exécuter ces requêtes SQL en utilisantexecuteBatch().

Le type de retour deexecuteBatch() est un tableauint indiquant le nombre d'enregistrements affectés par l'exécution de chaque instruction SQL.

Voyons un exemple de création et d’exécution d’un lot à l’aide de Statement:

Statement statement = connection.createStatement();
statement.addBatch("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName','Designation')");
statement.addBatch("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");
statement.executeBatch();

Dans l'exemple ci-dessus, nous essayons d'insérer des enregistrements dans les tablesEMPLOYEE etEMP_ADDRESS en utilisantStatement. Nous pouvons voir comment les requêtes SQL sont ajoutées dans le lot à exécuter.

3.2. Traitement par lots avecPreparedStatement

PreparedStatement est une autre classe utilisée pour exécuter des requêtes SQL. Il permet la réutilisation des instructions SQL et nous oblige à définir de nouveaux paramètres pour chaque mise à jour / insertion.

Voyons un exemple utilisantPreparedStatement. Tout d'abord, nous configurons l'instruction à l'aide d'une requête SQL codée enString:

String[] EMPLOYEES = new String[]{"Zuck","Mike","Larry","Musk","Steve"};
String[] DESIGNATIONS = new String[]{"CFO","CSO","CTO","CEO","CMO"};

String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES (?,?,?)";
PreparedStatement employeeStmt = connection.prepareStatement(insertEmployeeSQL);

Ensuite, nous parcourons un tableau de valeursString et ajoutons une requête nouvellement configurée au lot.

Une fois la boucle terminée, nous exécutons le lot:

for(int i = 0; i < EMPLOYEES.length; i++){
    String employeeId = UUID.randomUUID().toString();
    employeeStmt.setString(1,employeeId);
    employeeStmt.setString(2,EMPLOYEES[i]);
    employeeStmt.setString(3,DESIGNATIONS[i]);
    employeeStmt.addBatch();
}
employeeStmt.executeBatch();

Dans l'exemple ci-dessus, nous insérons des enregistrements dans la tableEMPLOYEE en utilisantPreparedStatement. Nous pouvons voir comment les valeurs à insérer sont définies dans la requête puis ajoutées au lot à exécuter.

4. Conclusion

Dans cet article, nous avons vu l’importance du traitement par lots des requêtes SQL lors de l’interaction avec des bases de données utilisant JDBC.

Comme toujours, le code lié à cet article se trouveover on Github.