Cours "Modèles pour la persistance des objets"

JDBC de base


Objectif du TP :

JDBC est l'API de base pour la persistance des données d'un programme Java dans une base de données relationnelle. Ce TP étudie les bases de l'utilisation de cette API.

Support de cours

Révision SQL : des TPs, support de cours


Installation de l'environnement

Tout d'abord vous devez installer la base de données des employés d'une entreprise qui sera utilisée pendant ce TP.

Cette base très simple contient 4 tables :

Un employé ne peut appartenir qu'à un seul département mais peut participer à plusieurs projets.

L'installation est décrite ici.

Cette base Oracle se trouve sur la machine euterpe , se nomme INFO. Le serveur Oracle écoute les requêtes des clients sur le port 1521 .

Voici un driver Oracle de type 4 pour la version 6 de Java et pour Oracle 11g (marche aussi avec Oracle 10g). Ce driver est compatible JDBC 4. Vous trouverez peut-être d'autres drivers JDBC plus récents à l'adresse http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html (section "Drivers / JDBC") mais vous pouvez faire le TP avec ce driver. Si vous allez sur le site d'Oracle, testez avec la dernière version du driver, même si elle ne correspond pas à la version d'Oracle que vous utilisez.


Pour apprendre les bases de l'API JDBC, ce TP utilise le modèle "procédural" (pas de réel modèle objet dans l'application Java ; appels JDBC de la couche client qui travaillent directement avec les tables de la base de données) pour travailler avec une base de données préexistante. Dans les TPs suivants on s'appuiera sur un modèle objet implémenté avec des classes Java, avec une structure des tables de la base de données déduite de ce modèle objet.


Etude d'un exemple

  1. Étudiez la classe Test1.java. Ajoutez la fermeture des ressources JDBC (Statement et Connection) et exécutez votre code.
  2. Modifiez l'ordre SQL pour avoir le nom et le nombre d'employés de chacun des départements.

Correction

Test1.java

Test1.java avec fermeture automatique des ressources (nécessite le JDK 7)


Utiliser un fichier de propriétés pour se connecter

Pour améliorer la portabilité de vos programmes, il est conseillé de ne pas écrire "en dur" dans le programme les informations nécessaires à la connexion. Ces informations peuvent être incluses dans un fichier de propriétés. On peut ainsi modifier ces informations sans recompiler les classes qui les utilisent. Attention à ne pas mettre d'espaces en fin de ligne dans le fichier de propriétés : ils seraient inclus dans les valeurs des propriétés.

Un fichier de propriétés a le format suivant :

prop1 = val1
prop2 = val2 

Étudiez la classe ConfigConnection et modifiez votre programme de l'exercice 1 pour l'utiliser. Version de la classe avec fermeture automatique des ressources (nécessite le JDK 7).

Correction

Test2.java
Fichier de propriétés


Modification des données

Connectez-vous directement à la base de données par sqlplus. Avant de lancer chaque classe Java, visualisez les données qui devraient changer et vérifiez que les modifications ont bien été effectuées par le programme Java.

  1. Écrivez un programme Java qui ajoute un employé. Vous devez enlever le mode "autocommit" qui lance un commit automatique après chaque requête.
    Remarque : le driver Oracle que vous utilisez fait un commit automatique lors de le fermeture de la connexion. Ne vous appuyez pas sur ce fait car d'autres drivers ou même une version future du driver peuvent avoir un comportement différent. Il faut donc toujours lancer un commit ou un rollback explicite à la fin de la session de travail si des données ont été modifiées.
  2. Ce programme augmente aussi de 10 % le salaire des employés qui ont les 3 plus petits salaires. Indications.

Correction

TestModif.java


Requêtes paramétrées

Utilisez des requêtes paramétrées pour

    1. avoir les noms, les numéros de département, les salaires et les commissions des employés du département 10, en utilisant 1 paramètre pour le numéro de département ; vous afficherez "Pas de commissions" si un employé a une commission null.
    2. augmenter de 15,5 % tous les employés du département 10, en utilisant 2 paramètres pour le pourcentage d'augmentation (ici 15,5) et le numéro de département.
    3. afficher à nouveau les noms, les numéros de département, les salaires et les commissions des employés du département 10.
    4. afficher les noms, les numéros de département, les salaires et les commissions des employés du département dont le total des salaires est le plus grand. Ces modifications peuvent être faites en un seul ordre SQL mais pour les besoins de l'exercice, récupérez d'abord le numéro du département et ensuite utilisez la requête paramétrée du a. pour faire afficher les informations demandées

Correction

Test3.java

Test3.java avec fermeture automatique des ressources (nécessite le JDK 7)


Toujours les requêtes paramétrées

    Une requête paramétrée est vraiment utile quand elle est exécutée de nombreuses fois avec des valeurs différentes des paramètres.         

    Dans la classe Test4.java, utilisez un tableau Java à 2 dimensions qui contient des numéros de départements et des pourcentages d'augmentation pour augmenter tous les employés de ces départements du pourcentage indiqué. Pour simplifier vous supposerez que les pourcentages d'augmentation sont des nombres entiers.
    Pour pouvoir vérifier, vous ferez afficher les salaires des départements concernés avant et après les augmentations.
    Utilisez les requêtes de l'exercice précédent.

    Lancez le programme plusieurs fois de suite. Est-ce que toutes les modifications sont bien prises en compte ?

Correction

Test4.java


Méta-données

Écrivez une classe Meta.java qui utilise les "meta données" pour afficher les noms des colonnes et le nom du type de données qu'elles contiennent pour l'ordre SQL "SELECT * FROM emp"
Essayez ensuite l'ordre "SELECT matr, substr(nomE,1,3), sal + coalesce(comm,0) GAIN FROM emp".

Correction

Meta.java


Transaction

Transfert de commission : écrivez une méthode pour transférer une commission d'un employé ("source") à un autre employé ("destination"). La méthode prend en paramètre les matricules des 2 employés. Vous utiliserez la notion de transaction pour, par exemple, remettre la commission à l'employé "source" s'il est impossible d'ajouter la commission à l'employé "destination".

Décomposez cette opération : lecture de la commission de l'employé "source", puis mise à NULL de cette commission, puis modification de la commission de l'employé "destination". Le but de cet exercice est de simuler une opération complexe comportant plusieurs ordres SQL.

Prévoyez les cas particuliers : l'employé "source" n'a pas de commission, un matricule d'employé n'existe pas, etc. Si l'employé destination a déjà une commission, la commision de l'employé source est ajoutée à sa commision.

Pour éviter les mises à jour perdues entre la lecture de la commission de l'employé "source" et la mise à NULL de cette commission, effectuez un blocage pessimiste de cet employé ( avec un "select for update").

Pour simplifier le test de votre programme, passez les matricules des 2 employés concernés en paramètres de la ligne de commande java.

Voici un squelette de classe que vous pouvez utiliser si vous le souhaitez.

Correction

Transaction.java


Retour