TD de Programmation Orientée Objet
s

JDBC

Corrigé

dernière modification par Philippe.Genoud@imag.fr.

Pour télécharger les sources complets de la solution : CorrigeTPJDBCsrc.zip

Le programme DemoJDBC lit les paramètres de connexion dans un fichier "properties". Le nom de ce fichier properties est spécifié en argument de la ligne de commande au lancement du programme.

Le fichier de configuration contient les propriétés suivantes :

Exemple : fichier bdOracle.properties pour une connexion à Oracle sur hoff

# fichier de proprietés pour une connexion à la base Oracle ufrima sur hoff
jdbcDriver=oracle.jdbc.driver.OracleDriver
dataBaseUrl=jdbc:oracle:thin:@hoff.imag.fr:1521:ufrima
userName=genoud
passwd=****** 

Pour lancer le programme, ne pas oublier d'indiquer dans le classpath le fichier jar ou zip contenant les classes du driver. Ainsi pour exécuter le programme avec le fichier properties précédent on utilisera la commande suivante (en supposant que les classes du driver jdbc sont dans classes12.zip qui se trouve dans le même répertoire que l'application) :

Sous Windows

java -cp .;classes12.zip DemoJDBC bdOracle.properties

Sous Unix :

java -cp .:classes12.zip DemoJDBC bdOracle.properties

 

 

Source complet DemoJDBC.java
  1 import java.io.BufferedReader;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.FileNotFoundException;
  5 import java.io.FileReader;
  6 import java.io.IOException;
  7 import java.sql.Connection;
  8 import java.sql.DriverManager;
  9 import java.sql.PreparedStatement;
 10 import java.sql.ResultSet;
 11 import java.sql.ResultSetMetaData;
 12 import java.sql.SQLException;
 13 import java.sql.Statement;
 14 import java.util.Properties;
 15 import java.util.StringTokenizer;
 16 
 17 
 18 /**
 19  * Programme de démonstration de JDBC.
 20  * Permet de se connecter à une BD Oracle et de tester différentes commandes SQL sur
 21  * une table représentant les consommations de café de différents programmeurs.
 22  *
 23  * Les différentes opérations possibles sont :
 24  * <OL>
 25  *   <LI>Créer la table</LI>
 26  *   <LI>Supprimer la table</LI>
 27  *   <LI>charger la table depuis un fichier</LI>
 28  *   <LI>Afficher le nom de la personne qui a consommé le plus de tasses de café en une
 29  *       journée ainsi que sa consommation ce jour là.</LI>
 30  *   <LI>Afficher le nombre total de tasses consommées.</LI>
 31  *   <LI>Afficher le nombre total de tasses consommées par un programmeur donné et
 32  *        le détail des consommations de celui-ci.</LI>
 33  *   <LI>Afficher les méta données concernant le résultat d"une requête quelconque</LI>
 34  *   <LI>Exécuter une requête quelconque saisie au clavier et afficher ses résultats</LI>
 35  * </OL>
 36  *<p>
 37  *   Les paramètres d"accès à la BD (classe du driver, url, nom d"utilisateur et mot de
 38  *   passe ) sont fixés dans un fichier properties spécifié en argument de la ligne de
 39  *   commande au lancement du programme. La forme de ce fichier est la suivante :
 40  *</p>
 41  *<pre>   
 42  *     jdbcDriver=oracle.jdbc.driver.OracleDriver
 43  *     dataBaseUrl=jdbc:oracle:thin:@hoff.imag.fr:1521:ufrima
 44  *     userName=genoud
 45  *     passwd=xxxxxxxx
 46  *</pres>
 47  *   @author Philippe Genoud (Philippe.Genoud@imag.fr)
 48  */
 49 public class DemoJDBC {
 50     
 51     private static Connection con;
 52     private static Statement stmt;
 53     
 54     /**
 55      * Création de la table JoltData. La création n"a lieu que si la
 56      * table JoltData n"existe pas encore. Sinon un message le signale
 57      * sur la console.
 58      */
 59     public static void creerTable() throws SQLException {
 60         stmt.executeUpdate("create table JoltData ("+
 61                 "programmer varchar (32),"+
 62                 "day varchar (3),"+
 63                 "cups integer)");
 64         System.out.println("table joltdata créée");
 65     }
 66     
 67     /**
 68      * initialisation de la table avec quelques valeurs
 69      */
 70     public static void initTable() throws SQLException {
 71         stmt.executeUpdate("INSERT INTO JoltData VALUES ("Gilbert", "Mon", 1)");
 72         stmt.executeUpdate("INSERT INTO JoltData VALUES ("Wally", "Mon", 2)");
 73         stmt.executeUpdate("INSERT INTO JoltData VALUES ("Edgar", "Tue", 8)");
 74         System.out.println("table joltdata supprimée");
 75     }
 76     
 77     /**
 78      * destruction de la table.
 79      */
 80     public static void supprimerTable() throws SQLException {
 81         stmt.executeUpdate("drop table JoltData");
 82     }
 83     
 84     /**
 85      * intialiasitation de la table JoltData à partir des données lues dans un fichier texte.
 86      */
 87     public static void chargerBase() throws SQLException {
 88         System.out.print("Nom du fichier : ");
 89         String nomFichier = LectureClavier.lireChaine();
 90         BufferedReader fichierEntree = null;
 91         try {
 92             // ouverture du fichier
 93             fichierEntree = new BufferedReader(new FileReader(nomFichier));
 94             
 95             PreparedStatement ps = con.prepareStatement("insert into JoltData values (?, ?, ?)");
 96             
 97             String ligneCour;  // la ligne courante
 98             
 99             while ((ligneCour = fichierEntree.readLine()) != null) {
100                 // traitement de la ligne courrante.
101                 // parcours des élements (tokens) de cette ligne avec un objet StringTokenizer
102                 // classe définie dans java.util
103                 StringTokenizer st = new StringTokenizer(ligneCour);
104                 String nom = st.nextToken();
105                 String jour = st.nextToken();
106                 int nbc = Integer.parseInt(st.nextToken());
107                 ps.setString(1,nom);
108                 ps.setString(2,jour);
109                 ps.setInt(3,nbc);
110                 ps.executeUpdate();
111                 
112             }
113             
114             ps.close();
115             // fermeture du fichier
116             fichierEntree.close();
117         } catch (IOException ioe) {
118             System.out.println("Erreur lecture dans le fichier" + nomFichier);
119             System.out.println(ioe.getMessage());
120             
121         }
122     }
123     
124     /**
125      * Affiche le nom de la personne qui a consommé le plus de tasses de café en une journée ainsi
126      * que sa consommation ce jour là, puis la liste des personnes ordonnee par ordre décroissant
127      * du nombre de consommations.
128      *
129      */
130     public static void nbreTassesMax() throws SQLException   {
131         ResultSet rs  = stmt.executeQuery("SELECT * FROM joltdata ORDER BY cups DESC");
132         if ( rs.next()) { // pour accéder à la première ligne du ResultSet
133             // si celui-ci n"est pas vide
134             System.out.println("Le plus gros consommateur de café en une journée est : " + rs.getString(1));
135             System.out.println("Sa plus grosse connsommation en une journée est : " + rs.getInt(3));
136             System.out.println("Celle-ci a eu lieu : " + rs.getString(2));
137             System.out.println();
138             
139             while (rs.next()) { // pour chaque ligne du result set
140                 System.out.println(rs.getString(1) + ",\t" +    // le nom
141                         rs.getString(2) + ",\t" +         // le jour
142                         rs.getInt(3));              // la quantité
143             }
144         }
145         rs.close();
146         
147     }
148     
149     /**
150      * affiche le nombre total de tasses consommées.
151      */
152     public static void nbreTotalTasses() throws SQLException{
153         ResultSet rs  = stmt.executeQuery("SELECT SUM(cups) FROM joltdata");
154         if (rs.next()) // pour accéder à la première ligne du ResultSet
155             // si celui-ci n"est pas vide
156             System.out.println("le nombre total de tasses consommées " + rs.getInt(1));
157         else
158             System.out.println("la table est vide");
159         rs.close();
160     }
161     
162     /**
163      * Renvoie le nombre total de tasses consommées par un programmeur donné et
164      * affiche le détail des consommations de celui-ci.
165      */
166     public static void nbreTotalTassesPgm() throws SQLException {
167         System.out.print("nom du programmeur ");
168         String programmer = LectureClavier.lireChaine();
169         ResultSet rs  = stmt.executeQuery("SELECT day,cups FROM joltdata WHERE programmer=""
170                 + programmer + """);
171         int nbt = 0;   // le nombre total de tasses
172         int nbtj = 0;  // le nombre de tasses par jour
173         while   (rs.next() ) {
174             nbtj = rs.getInt("cups");
175             System.out.println(rs.getString("day") + " : " + nbtj);
176             nbt += nbtj;
177         }
178         
179         System.out.println("Le nombre total de tasses consommé par " +
180                 programmer + " est " + nbt);
181         rs.close();
182         
183     }
184     
185     /**
186      * Exécute une requête libre définie par une chaîne donnée au clavier et
187      * affiche les méta données concernant le résultat de cette requête
188      * quelconque.<BR>
189      * <UL>
190      * <LI>Si la command renvoie un ResultSet (Query) cette méthode indique :
191      *     <UL>
192      *     <LI>le nombre de colonnes,  et pour chaque colonne le nom et le type
193      *     de la colonne.</LI>
194      *     <LI>le contenu du resultSet est affiché ligne par ligne sur la sortie
195      *     standard.</LI>
196      *     </UL>
197      * </LI>
198      * <LI>Si la commande ne renvoie pas un ResultSet (Update) cette méthode
199      * indique le nombre de lignes de la table qui ont été modifiées.
200      * <LI>
201      * </UL>
202      */
203     public static void requeteLibreEtMetaDonnees() throws SQLException {
204         System.out.print("Rentrez votre  requette :");
205         String cmd = LectureClavier.lireChaine();
206         
207         if (stmt.execute(cmd)) {
208             ResultSet rs = stmt.getResultSet();
209             
210             // consultation et affichage des meta données
211             ResultSetMetaData rsmd = rs.getMetaData();
212             int numberOfColumns = rsmd.getColumnCount();
213             System.out.println("le résultat contient " + numberOfColumns + " colonnes");;
214             for (int i = 1; i <= numberOfColumns; i++) {
215                 System.out.println("--------------------------------");
216                 System.out.println("Colonne : " + i + "\nNOM " + rsmd.getColumnName(i)
217                 + " TYPE : " + rsmd.getColumnTypeName(i) );
218             }
219             System.out.println("--------------------------------");
220             
221             //affichage du resutlat de la requête
222             System.out.println("Résultats de la requête\n");
223             while (rs.next()) {
224                 for (int i = 1; i <= numberOfColumns; i++)
225                     System.out.print(rs.getString(i) + " ");
226                 System.out.println();
227             }
228             rs.close();
229         } else {
230             System.out.println("Requête effectuée");
231             System.out.println("Nombre de lignes modifiées " + stmt.getUpdateCount());
232         }
233     }
234     
235     /**
236      * affiche le menu présentant les différentes opérations possibles
237      */
238     public static void affMenu() {
239         System.out.println("\n\n------------------------------------------");
240         System.out.println("1 : Créer et initialiser la table");
241         System.out.println("2 : Détruire la table");
242         System.out.println("3 : Initaliser la table");
243         System.out.println("4 : Consommation max (exo 2.1)");
244         System.out.println("5 : Nombre total de tasses (exo 2.2)");
245         System.out.println("6 : Nombre total tasses pour un programmeur (exo 2.3)");
246         System.out.println("7 : Requete Libre et Méta données (exo 3)");
247         System.out.println("8 : Charger les données depuis un fichier");
248         System.out.println("0 : Quitter l"application");
249     }
250     
251     
252     /**
253      * charge une classe de driver jdbc. Si le driver spécifié n"est pas trouvé l"exécution
254      * de l"application est interrompue.
255      * @param driver name le nom (Fully qulified Name) de la classe du driver.
256      */
257     public static void chargerDriver(String driverName) {
258         // chargement du Driver Oracle
259         try {
260             Class.forName(driverName);
261             System.out.println("Driver " + driverName + "chargé");
262         } catch (ClassNotFoundException e) {
263             System.out.println("erreur dans le chargement du driver");
264             System.exit(0);
265         }
266     }
267     
268     /**
269      * création d"une connexion. Si la connexion ne peut être créée l"application
270      * est interrompue.
271      * @param url l"url spécifiant la BD.
272      * @param username le nom de l"utilisateur
273      * @param passwd son mot de passe.
274      * @param return la ref de l"objet connexion créé.
275      */
276     public static Connection ouvrirConnexion(String url, String username, String passwd) {
277         
278         Connection con =null;
279         try {
280             con = DriverManager.getConnection(
281                     url,
282                     username,
283                     passwd);
284             
285         } catch (SQLException e) {
286             System.out.println("Impossible de se connecter à "+ url);
287             System.out.println("avec comme nom d"utilisateur : " + username);
288             System.out.println("et comme mot de passe " + passwd);
289             System.out.println(e.getMessage());
290             System.exit(0);
291         }
292         return con;
293     }
294     
295     public static void main(String[] args) {
296         
297         int rep; // la réponse de l"utilisateur pour le menu principal
298         String propFileName = null; // le nom du fichier properties contenant les
299         // infos de connexion à la BD (classe du driver jdbc
300         // et url de connexion
301         
302         if (args.length > 0)
303             propFileName = args[0];
304         else {
305             System.out.println("usage : java DemoJDBC propertiesFile");
306             System.exit(0);
307         }
308         
309         // lecture des paramètres BD dans le fichier properties
310         
311         Properties options = new Properties();
312         try {
313         options.load(new FileInputStream(new File(propFileName)));
314         }
315         catch (FileNotFoundException fne) {
316             System.out.println("fichier " + propFileName + " non trouvé");
317             System.exit(0);
318         }
319         catch (IOException ioe) {
320             System.out.println("problème lecture du ficher properties");
321             System.exit(0);
322         }
323         
324         String driverClassName = options.getProperty("jdbcDriver");
325         String dataBaseUrl = options.getProperty("dataBaseUrl");
326         String nom = options.getProperty("userName");
327         String motDePasse = options.getProperty("passwd");
328        
329         // chargement du driver
330         chargerDriver(driverClassName);
331         
332         // ouverture d"une connexion
333         con = ouvrirConnexion(dataBaseUrl,nom, motDePasse);
334                 
335         System.out.println("utilisateur " + nom + " connecté à " + dataBaseUrl);
336         
337         //création d"un objet statement qui sera utilisé par toutes les
338         //opérations d"accès à la BD. Fermeture de la connexion et
339         // arrêt du programme en cas d"erreur
340         try {
341             stmt = con.createStatement();
342         } catch (SQLException sqle) {
343             System.out.println("Problème à la création d"un Statement " +
344                     sqle.getMessage());
345             try {
346                 con.close();
347             } catch (SQLException e) {
348                 e.printStackTrace(); // que faire de plus ?
349             }
350             System.exit(0);
351         }
352         
353         do {
354             affMenu();
355             System.out.print("votre choix : ");
356             
357             
358             rep = LectureClavier.lireEntier();
359             System.out.println("\n\n");
360             try {
361                 switch (rep) {
362                     case 0 : System.out.println("au revoir");
363                     break;
364                     case 1 : creerTable();
365                     break;
366                     case 2 : supprimerTable();
367                     break;
368                     case 3 : initTable();
369                     break;
370                     case 4 : nbreTassesMax();
371                     break;
372                     case 5 : nbreTotalTasses();
373                     break;
374                     case 6 : nbreTotalTassesPgm();
375                     break;
376                     case 7 : requeteLibreEtMetaDonnees();
377                     break;
378                     case 8 : chargerBase();
379                     break;
380                     
381                     default:
382                         System.out.println("valeur erronée !");
383                 }  // end switch
384             } catch (SQLException sqle) {
385                 System.out.println("Problème SQL\n" + sqle.getMessage());
386             } catch (NumberFormatException nfe) {
387                 System.out.println("\nsaisie incorrecte\n");
388             }
389         } while (rep != 0);
390         
391         // Fermer la connexion à la BD
392         try {
393             stmt.close();
394             con.close();
395         } catch (SQLException sqle) {
396             // que faire de plus ?
397             sqle.printStackTrace();
398         }
399     }
400     
401 }
402