TP JDBC — Requêtes, transactions et métadonnées

Travaux pratiques d’approfondissement JDBC sur H2 en mémoire : DAO avec PreparedStatement, prévention de l’injection SQL, transactions atomiques, mise à jour en lot, métadonnées de ResultSet et navigation scrollable.
Auteur
Affiliations

Université de Toulon

LIS UMR CNRS 7020

Date de publication

2026-11-02

Comment exécuter ce TP

Toutes les cellules de ce notebook sont exécutées, y compris les squelettes : ils compilent tels quels et retournent des valeurs par défaut (liste vide, false) tant que les TODO ne sont pas complétés. Modifiez les cellules marquées TODO, puis réexécutez tout le notebook depuis le début pour repartir d’un état de base de données propre. La preuve de complétion est le rendu CI : la section Validation doit afficher OK-01 à OK-05. Attention, piège connu de la flotte : l’option //| execute: false est ignorée pour les cellules {java} — toute cellule du fichier s’exécute réellement au rendu.

E1 — La méthode qui manque

Un DAO JDBC se lit en trois temps : ouvrir une connexion, préparer la requête avec des paramètres liés, parcourir le ResultSet. Complétez la méthode ci-dessous en exécutant la requête préparée et en alimentant la liste resultat avec la colonne NOM, en respectant le try-with-resources déjà en place.

Résultat attendu une fois le TODO complété : [Bastille, Gare de Lyon, Nation].

E2 — Tuez l’injection

La méthode suivante construit sa requête par concaténation : c’est la faille d’injection SQL classique. Observez d’abord son comportement avec une entrée malveillante, puis écrivez la version sûre nomExact avec un paramètre lié. Comme en E1, la version vide retourne une liste vide par défaut.

Résultat attendu : 8 (tous les arrêts exfiltrés), puis 0 (aucun arrêt ne porte ce nom).

E3 — Tout ou rien

Écrivez un virement atomique entre deux comptes : soit les deux UPDATE sont validés, soit aucun ne l’est. Le compte débité ne doit jamais descendre sous zéro. Le gestionnaire solde est fourni ; complétez transferer en pilotant vous-même le commit.

Résultat attendu : 5000/3000, puis virement validé et 4000/4000, puis solde inchangé après le virement impossible.

E4 — Mille inserts, une bourrasque

Insérer 1000 lignes une par une coûte 1000 allers-retours vers le moteur. La mise à jour en lot (addBatch / executeBatch) les regroupe en une seule bourrasque. Chronométrez la version ligne par ligne, puis comparez avec la version en lot fournie.

Résultat attendu après chaque version : Lignes dans TRAJET : 1000.

E5 — Le ResultSet se raconte

Un ResultSet sait décrire sa propre structure : demandez ses métadonnées colonnes, puis faites reculer son curseur scrollable de la dernière ligne à la première.

Résultat attendu : ID INTEGER | NOM VARCHAR | LIGNE VARCHAR, puis les 8 noms en ordre alphabétique inverse. Point de discussion : les noms de colonnes apparaissent en MAJUSCULES car H2 v2 stocke les identifiants non quotés en uppercase — JDBC renvoie les filtres tels quels, contrairement à PostgreSQL nativement en minuscules.

Validation

Exécutez toutes les cellules depuis le début. Chaque ligne ci-dessous doit afficher OK.

Compte rendu

Exportez le notebook rendu. Vous déposez : la sortie de la cellule de vérification de E2 (8 puis 0) accompagnée de trois phrases expliquant pourquoi un paramètre lié stoppe l’injection là où la concaténation ouvre une porte ; ainsi que les lignes de E3 assurant le contrôle transactionnel (setAutoCommit(false), commit(), rollback()), à mettre en évidence dans votre code soumis.

Réutilisation