Traitement par lots dans JDBC

Haut Java

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Introduction

Java Database Connectivity (JDBC) est une API Java utilisée pour interagir avec les bases de données. Le traitement par lots regroupe plusieurs requêtes en une seule unité et les transmet en un seul trajet réseau à 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'introduction ici.

2. Pourquoi le traitement par lots?

Les performances 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 où la séquence des requêtes envoyées est importante.

Toute erreur survenant lors de l'exécution doit entraîner une restauration des données transmises par les requêtes précédentes, le cas échéant.

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 deuxième instruction échoue. Dans cette situation, il n'y a pas de restauration des données insérées par la première instruction, ce qui entraîne une incohérence des données.

Nous pouvons atteindre 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 restauration en cas d'exceptions, mais dans ce cas, nous continuons à frapper la base de données à plusieurs reprises pour chaque instruction.

3. Comment effectuer le traitement par lots

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

3.1. Traitement par lots à l'aide de Statement

Avec JDBC, le moyen le plus simple d'exécuter des requêtes sur une base de données consiste à utiliser l' objet Statement .

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

Le type de retour de executeBatch () est un tableau int indiquant combien d'enregistrements ont été 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 tables EMPLOYEE et EMP_ADDRESS à l' aide de Statement . Nous pouvons voir comment les requêtes SQL sont ajoutées dans le lot à exécuter.

3.2. Traitement par lots à l'aide de PreparedStatement

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 utilisant PreparedStatement. Tout d'abord, nous configurons l'instruction à l'aide d'une requête SQL encodée sous forme de chaîne:

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 valeurs String et ajoutons une requête nouvellement configurée au lot.

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

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 table EMPLOYEE à l' aide de PreparedStatement. 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 à quel point le traitement par lots des requêtes SQL est important lors de l'interaction avec les bases de données à l'aide de JDBC.

Comme toujours, le code lié à cet article est disponible sur Github.

Fond Java

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS