JAVA


Java 2 Entreprise Edition (J2EE) JDBC





|

    J2EE est une norme qui regroupe un ensemble de normes concernant les objets, 
    protocoles, ... permettant le développement d'application d'entreprise robuste, ainsi
    que la création de serveur d'applications.
    Contenu de la norme J2EE : 
    	- Modèle de développement MVC (Model - View - Controler) via des API de base
    		- Model : EJB (Entreprise Java Bean) gestion des données et traitements
    		- View : JSP (Java Server Page) Gestion de l'affichage vers 
    			le terminal client
    		- Controler : Servlet Interface entre les données et l'affichage.
    	- Ensemble de services
    		- JDBC : Accès aux données
    		- JNDI : Annuaire d'accès aux objets distribués
    		- JTA : Moniteur transactionnel
    		- XML : Représentation universelle des données
    		- ...
    	- Conteneurs d'objets : 
    		- Moteur de servlet
    		- Moteur d'EJB
    		
Serveur d'application : 
    	Le rôle du serveur d'application est de faire fonctionner les applications
    	d'entreprises écrites en Java.
    	Le serveur d'application prend en charge l'environnement permettant
    	à l'application d'être disponible sur le web. C'est à dire qu'il fournit
    	un certain nombre de services  : 
    		- Service de nommage
    		- Service de gestion des transactions
    		- Service de loadbalancing / failover
    		- Service de sécurité
    		- Service d'administration
    		- Service d'accès aux données
    		- Service de gestion des messages		
    


|

Modèle MVC : Servlet / EJB ou JavaBean / JSP 
	Principe de fonctionnement : 
		1 : Envoi d'une requette HTTP vers une servlet
		2 : Interprétation de la demande par la servlet et
			Redirection de la demande vers l'EJB ou le JavaBean
		3 : Traitement de la demande avec ou sans accès à la BDD
		4 : Renvoi du résultat vers la servlet
		5 : Redirection du résultat vers un JSP
		6 : Renvoi de la réponse vers le client


Schéma de fonctionnement : 
    

Servlet : (p.19)
	Classe Java permettant de gérer les flux HTTP.
	Dans le modèle MVC elle joue le rôle de contrôleur.
	Classe java simple et performante.

JSP (Java Server Page) : (p 20)
	Un Jsp est une page HTML contenant du code Java.
	Un JSP est compilé et exécuté comme une servlet par le serveur d'application

EJB (Entreprise Java Bean) : (p 20)
	Composant distribué accessible via un annuaire. Il contient la logique métier.
	Il existe 2 types d'EJB
		- EJB Session : Gère les traitements
		- EJB Entité : Gère les données


|

Accès aux données : API JDBC (Java DataBase Connectivity)
    Norme permettant de coder une seule fois pour accéder à toutes les bases de données
    Packages de l'API : 
      - java.sql : Connexion, Lecture, Ecriture, métadonnées de façon classique.
      - javax.sql : Gestion des pools de connexion et du 2 phases commit.
     
    - Pilote JDBC : (p 38)
    	Il existe 4 types de pilotes JDBC. L'utilisation de l'un ou l'autre des types 
    	n'influe pas sur le code développé.
    		- Type 1 : JDBC-ODBC
    			Le principe de ce type de pilote est de s'appuyer sur ODBC pour 
    			accéder à la base de données.
    			ODBC étant peu performant, l'ajout d'une couche dégrade 
    			les performances.
    		- Type 2 : JDBC-Pilote natif
    			Le pilote JDBC fait appel à des fonctions propriétaires de la BDD 
    			et/ou au système d'exploitation.
    		- Type 3 : JDBC-Middleware
    			Le pilote fait appel à un logiciel qui lui fait appel à un pilote 
    			de type 2.
    		- Type 4 : Ecrit entièrement en Java (donc portable) 
    			Le pilote communique directement avec la BDD. La performance et la
    			simplicité de mise en oeuvre rendent ce pilote très attractif.
    
    Classes permettant l'accès à une table : 
    - java.sql.DriverManager : Chargement du pilote JDBC
    - java.sql.Connection : Obtention et gestion d'une connexion à la BDD
    - java.sql.Statement : Permet d'exécuter des requêtes simples
    - java.sql.PrepareStatement : Permet de créer des ordres SQL pré-compilés
    - java.sql.CallableStatement : Permet d'exécuter des procédures stockées
    - java.sql.ResultSet : Permet la lecture des enregistrements résultant de la requête.


|

JDBC par l'exemple :   
    
    Pour la totalité de la formation, nous allons utiliser le driver JDBC fournit par IBM
    pour accéder à l'AS400.
    Les classes de ce driver sont contenues dans un fichier jar : JT400.jar.
    Il se situe dans l'IFS : /QIBM/ProdData/Public/HTTPA/Java/lib/jt400.jar
    Ce driver est de type 4, c'est à dire entièrement écrit en Java.
    
    Exemple : 
 package formation.exercice;
 import java.sql.*;
    
 public class JDBCDemo {

    public static void main(String[] args) {
       try{
          if(args.length==2){
            String user = args[0];
            String password = args[1];
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            Connexion dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //String requête SQL : 
            String strSql = "Select * from pays";
            //Création d'une requête
            Statement stmt = dbCon.CreateStatement();
            //Exécution de la requête
            ResultSet rs = stmt.executeQuery(strSql);
            while(rs.next()){
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String col1 = rs.getString(1);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String col2 = rs.getString(2);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String col3 = rs.getString(3);
              //Affichage du résultat
              StringBuffer strb = new StringBuffer();
              strb.append("Enregistrement n°");
              strb.append(i+1);
              strb.append(" : ");
              strb.append(col1);
              strb.append(" , ");
              strb.append(col2);
              strb.append(" , ");
              strb.append(col3);
              System.out.println(strb.toString());
              
            }
            rs.close();
            stmt.close();
            dbCon.close();
          }else{
            System.out.println("Paramètres insuffisants");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

    

|

JDBC L'exemple dans le détail :
    
    Class.forName : La classe Class est une classe abstraite.
    Elle permet de charger la classe passée en paramètre de façon à ce qu'elle
    soit utilisable.
    
    
    DriverManager :  classe abstraite.
    Elle permet d'établir la connexion à la base de données avec tous les drivers.

    Url JDBC : Toute les BDD sont accessibles via une URL de connexion. 
    Syntaxe : 
    	jdbc:<nom protocol>:<sous -nom><propriétés>
    	jdbc:as400://AS400; 
    
        
    Connection :  Classe qui représente la connexion courante.
    Cette classe va permettre de
    	- Créer des requêtes
    	- Vérifier le statut de la connexion
    Méthode de la classe : 
    	- close() : Ferme la connexion
    	- createStatement() : Crée une requête
    	- createPreparedStatement() : Crée une requête précompilée
    	- setAutoCommit() : Permet de modifier la gestion du contrôle de validation
    	- commit() : Valide une transaction
    	- rollback() : invalide une transaction
    	- setTransactionIsolation(int level) : Modifie le niveau d'isolation : 	
    		- None : Aucun 
    		- Read uncommitted : Enregistrement non verrouillé par la lecture
    		- Read Committed : Enregistrement verrouillé par la lecture
    		- Serialized : chaque action sur la BDD est écrite dans un journal
    			(Lecture comprise)
    		- setReadOnly(boolean readOnly) : Permet de faire une lecture de façon 
    		plus performante en positionnant read only
    
    	 
    	
    Statement stmt = dbCon.createStatement(); : 
    Statement est la classe qui va permettre d'exécuter une requête sans paramètre.
    L'instance de cette classe est crée par la classe connection.
    Statement permet la lecture et la maintenance des données (insert, update, delete)
    
    Méthode de la classe :
     	- setMaxRows(int max) : Donne le nombre maximal de lignes à lire.
     	- setQueryTimeOut(int seconds) : Donne le temps max d'exécution d'une requête.
     	- close() : ferme la requête SQL.
     	- execute(String sql) boolean : Exécute la requête et retourne un booléen 
     	indiquant que la requête s'est bien exécutée.
     		- getResultSet() ResultSet : Récupère les enregistrements lus
     		- getUpdateCount() int : Récupère le nombre d'enregistrements mis à jour
     	- excuteQuery(String sql) Resultset : Exécute une requête et renvoi le 
     	résultat de la lecture dans l'objet ResultSet.
     	- executeUpdate(String sql) int : Exécute une requête de mise à jour et 
     	retourne le nombre de lignes mises à jour. 0 indique que la requête n'a
     	mis à jour aucune ligne.
    
     	
    ResultSet rs = stmt.executeQuery(strSql); : 
    Cette classe représente le nombre d'enregistrements résultant de l'exécution d'une
    requête SQL de lecture.
    
    Méthode de la classe :
     	La classe ResultSet contient un ensemble de méthodes permettant de récupérer
     	la valeur des champs des enregistrements.
     	Ces méthodes sont : getXXXX où XXXX représente le type du champ.
     	Paramètres de ces méthodes : 
     		- int champ : Position du champ à lire dans la requête
     		- String nomChamp : Nom du champ à lire
     		
     	Exemple : 
     		rs.getString("nomvin");
     		rs.getString(1);
     		Ces 2 méthodes retournent le même résultat.
     		
     		Attention : L'indice de la première colonne est 1 et non 0 comme dans tous 
     		tableaux Java.
     		
     	Liste des méthodes page 76
     	- CHAR : getString
     	- Date : getDate
     	- NUMERIC : getInt, getLong, getDouble, ...
     	- TimeStamp : getTimeStamp
     	- ...
     	
     	- next() : permet de passer à l'enregistrement suivant.
     	- close() : Fermeture du curseur
     	- getMetaData() ResultSetMetaData : Retourne un objet contenant la définition
     	des données lues.
    
  

|

Méta-Données d'une requête : 
    
    Méthode de la classe ResultSet permettant d'accéder à la définition de la donnée : 
    getMetaData(). Cette méthode retourne la classe ResultSetMetaData.
    
    Méthode de la classe ResultSetMetaData : 
    	- getColumnCount() int : retourne le nombre de colonnes de la requête.
    	- getColumnName(int i) String : Retourne le nom de la colonne 
    	- getColumnLabel(int i) : Retrouve le label associé à la colonne (COLHDG)
    	- getColumnType(in i) int  : Retourne le type de la colonne.
    		Les types des colonnes sont définis comme constantes dans la classe 
    		java.sql.Types
    	- getPrecision(int i) : Longueur de la colonne
    	- getScale(int i) : Nombre de décimale de la colonne

Exercice

 package formation.exercice;
 import java.sql.*;
    
 public class JDBCMetaDataDemo {

    public static void main(String[] args) {
       try{
          if(args.length>2){
            String nomTable = args[0];
            //Déclaration du driver :
            
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            
            //Construire la requête sql en fonction de la table passée en paramètre 

            //Création d'une requête
			
	    //indiquer que l'on ne veut retourner qu'un nombre de ligne limité
			
            //Exécution de la requête

            //Lecture de la métadonnée
            //Boucler sur le nombre de colonnes de la requête
            //et afficher le nom, le type et la longueur de chaque colonne
			
			
	    //Fermeture du curseur, de la requête et de la connexion
          }else{
            System.out.println("Paramètres incorrect");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}
Corrigé

package formation.exercice;
 import java.sql.*;
    
 public class JDBCMetaDataDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String nomTable = args[0];
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            Connexion dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //String requête SQL : 
            StringBuffer strSql = new StringBuffer("Select * from ");
            strSql.append(nomTable);
            //Création d'une requête
            Statement stmt = dbCon.CreateStatement();
            //Limite du nombre d'enregistrements
            stmt.setMaxRows(0);
            //Exécution de la requête
            ResultSet rs = stmt.executeQuery(strSql.toString);
            //Nombre de colonnes
            int nbCols = rs.getMetaData().getColumnCount();
            for(inti=1; i<=nbCols;i++){
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String nomCol = rs.getMetaData().getColumnName(i);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String type = rs.getMetaData().getColumnTypeName(i);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              int longueur = rs.getMetaData().getPrecision(i);
              //Affichage du résultat
              StringBuffer strb = new StringBuffer();
              strb.append(nomCol);
              strb.append(" ");
              strb.append(type);
              strb.append(" ");
              strb.append(longueur);
              System.out.println(strb.toString());
            }
            rs.close();
            stmt.close();
            dbCon.close();
          }else{
            System.out.println("Paramètres insuffisants");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

|

Requêtes paramétrées et précompilées : 
    
    Une classe similaire à la classe Statement permet l'utilisation de requêtes précompilées,
    qui sont surtout utilisées pour le paramétrage des requêtes : PreparedStatement
    
    Exemple d'utilisation : 
package formation.exercice;
 import java.sql.*;
    
 public class JDBCPreparedDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1quot;
            //Connexion à la BDD
            Connection dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //String requête SQL : 
            String strSql = "Select * from pays where PR_NOM like ?";
            //Création d'une requête
            PreparedStatement pstmt = dbCon.prepareStatement(strSql);
            //Alimentation du paramètre 
            pstmt.setString(1,args[0]);
            //Exécution de la requête
            ResultSet rs = stmt.executeQuery();
            //Nombre de colonnes
            int nbCols = rs.getMetaData().getColumnCount();
            while(rs.next){
              //Récupération de la valeur de la colonne PR_NOM
              String nom = rs.getString("PR_NOM");
              //Récupération de la valeur de la colonne PR_COMMUNE
              String ville = rs.getString("PR_COMMUNE");
              System.out.println(nom  +" - " + ville);
            }
            rs.close();
            pstmt.close();
            dbCon.close();
          }else{
            System.out.println("Paramètres incorrects");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

|

La classe PreparedStatement :
    
    Méthodes principales : 
    	- getMetaData() ResultSetMetaData : Récupération de la méta-donnée
    	- close() : Fermeture du curseur
    	- clearParameters() : Suppression de toutes les valeurs des paramètres
    	- setXXX : Comme la classe ResultSet, la classe PreparedStatement contient 
    	un ensemble de méthodes qui alimente les paramètres de la requête.
    	Chaque méthode contient deux paramètres : 
    		- position du paramètre (type entier)
    		- Valeur du paramètre
    	Exemple de méthode : 
    		- CHAR : setString(int pos, String valeur)
    		- Date : setDate(int pos, java.sql.Date date)
    	Une autre méthode générique permet d'alimenter tous les paramètres : 
    	setObject(int pos, Object valeur, int type)
    	Il suffit d'indiquer en plus de la position et de la valeur, le type.
    	
Exercice

 package formation.exercice;
 import java.sql.*;
    
 public class JDBCMetaDataDemo {

    public static void main(String[] args) {
       try{
          if(args.length>2){
            String nomTable = args[0];
            //Déclaration du driver :
            
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            
            //Construire la requête sql en fonction de la table passée en paramètre 

            //Création d'une requête
			
	    //indiquer que l'on ne veut retourner qu'un nombre de ligne limité
			
            //Exécution de la requête

            //Lecture de la métadonnée
            //Boucler sur le nombre de colonnes de la requête
            //et afficher le nom, le type et la longueur de chaque colonne
			
			
	    //Fermeture du curseur, de la requête et de la connexion
          }else{
            System.out.println("Paramètres incorrects");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}
Corrigé

package formation.exercice;
 import java.sql.*;
    
 public class JDBCMetaDataDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String nomTable = args[0];
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            Connection dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //String requête SQL : 
            StringBuffer strSql = new StringBuffer("Select * from ");
            strSql.append(nomTable);
            //Création d'une requête
            Statement stmt = dbCon.CreateStatement();
            //Limite du nombre d'enregistrements
            stmt.setMaxRows(0);
            //Exécution de la requête
            ResultSet rs = stmt.executeQuery(strSql.toString);
            //Nombre de colonnes
            int nbCols = rs.getMetaData().getColumnCount();
            for(inti=1; i<=nbCols;i++){
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String nomCol = rs.getMetaData().getColumnName(i);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              String type = rs.getMetaData().getColumnTypeName(i);
              //Récupération de la valeur de la colonne 1 de l'enregistrement
              int longueur = rs.getMetaData().getPrecision(i);
              //Affichage du résultat
              StringBuffer strb = new StringBuffer();
              strb.append(nomCol);
              strb.append(" ");
              strb.append(type);
              strb.append(" ");
              strb.append(longueur);
              System.out.println(strb.toString());
            }
            rs.close();
            stmt.close();
            dbCon.close();
          }else{
            System.out.println("Paramètres insuffisants");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

|

Définition des données : MétaDonnée
    
    Il est possible de retrouver la définition d'une table sans exécuter une requête SQL. 
    La classe Connection possède une méthode permettant d'obtenir une instance de 
    la classe DatabaseMetaData.
    Cette classe permet de connaître : 
    	- les colonnes d'une table
    	- les clés primaires d'une table
    	- Les clés étrangères d'une table 
    	- Les index de la table
    	- les UDTs
    	- Les procédures stockées
    	- les droits sur les tables
    	- les tables
    	_ ....
    	
    Méthode de la classe : 
    	- ResultSet getColumns(String catalog, String schemaPattern,
				String tableNamePattern, String columnNamePattern)
	   Méthode qui retourne un ResultSet contenant la liste des colonnes 
	   de la table et les informations liés aux colonnes (type, longueur, ...)
		- String Catalog : représente le nom de la machine, peut être null
		- String schemaPattern : Représente le nom de la bibliothèque, peut être null
		- String tableNamePattern : nom de la table complet ou partiel, peut être null
		- String columnPattern : nom de la colonne complet ou partiel
		
	- ResultSet getPrimaryKeys(String catalog, String schema,
				String table)
	  Méthode qui retourne un Resultset contenant la liste des colonnes qui 
	  définissent la clé primaire de la table
		- String Catalog : représente le nom de la machine, peut être null
		- String schema : Représente le nom de la bibliothèque, peut être null
		- String table : nom de la table 
		
	- ResultSet getExportedKeys(String catalog, String schema,
				String table) throws SQLException;
	  Méthode qui retourne un Resultset contenant la liste des colonnes qui 
	  définissent les clés étrangères de la table
		- String Catalog : représente le nom de la machine, peut être null
		- String schema : Représente le nom de la bibliothèque, peut être null
		- String table : nom de la table 
		
	- ResultSet getIndexInfo(String catalog, String schema, String table,
			boolean unique, boolean approximate)
	  Méthode qui retourne un Resultset contenant la liste des colonnes présentes 
	  dans les index de la table.
		- String Catalog : représente le nom de la machine, peut être null
		- String schema : Représente le nom de la bibliothèque, peut être null
		- String table : nom de la table 
		- boolean unique : indique que l'on ne souhaite voir que les index uniques
		- boolean approximate : nom de la table 
		
	- ResultSet getTablePrivileges(String catalog, String schemaPattern,
				String tableNamePattern)
	  Méthode retournant un ResultSet contenant les droits des tables
		- String Catalog : représente le nom de la machine, peut être null
		- String schemaPattern : Représente le nom de la bibliothèque, peut être null
		- String tableNamePattern : nom de la table complet ou partiel
		
	Utilisation de la classe : 
		java.sql.Connection dbCon;
		//Obtention de la méta-donnée
		java.sql.DatabaseMetadata dbm = dbCon.getMetaData();
		//Liste des colonnes de la table vins
		ResultSet rs = dbCon.getColumns(null,null,"Vins",null);
		

Exercice : 

package formation.exercice;
 import java.sql.*;
    
 public class JDBCProcedureDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String nomTable = args[0];
            //Déclaration du driver : 
            
            //Url de connexion 
            
            //Connexion à la BDD
            
            
            //Obtention de la classe DatabaseMetadata: 
            
            
            //Obtention des colonnes de la table
            
            //Obtention du nombre de colonnes du ResultSet
             
            //Boucler sur les enregistrements
            while(rs.next(){
            	//Création d'un objet StringBuffer pour alimenter l'affichage
                Stringbuffer strb = new StringBuffer();
                //Boucler sur les colonnes du ResultSet pour afficher toutes
                //les propriétés des colonnes de la table
            	for(){
            	  //Obtention du nom de la propriété à afficher
            	  String nom = 
            	  //Obtention de la valeur de la colonne
            	  String val =   
            	  strb.append(" | ");
            	  strb.append(nom);
            	  strb.append(" : ");
            	  strb.append(val);
            	}
            	  //Affichage du nom et de la valeur
            	System.out.println(strb.toString());
            }
            //Fermeture des objets SQL
          }else{
            System.out.println("Paramètres insuffisants");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}
Corrigé

package formation.exercice;
 import java.sql.*;
    
 public class JDBCProcedureDemo {

    public static void main(String[] args) {
       try{
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400/BDVIN1"
            //Connexion à la BDD
            Connection dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //Obtention de la classe DatabaseMetadata: 
            DatabaseMetaData dbm = dbCon.getMetaData();
            
            //Obtention des colonnes de la table
            ResultSet rs = dbm.getColumns(null,null,nomTable,null);
            //Obtention du nombre de colonnes de du ResultSet
            int nbCol = rs.getMetaData().getColumnsCount();
            //Boucler sur les enregistrements
            while(rs.next(){
            	//Création d'un objet StringBuffer pour alimenter l'affichage
                Stringbuffer strb = new StringBuffer();
            	for(int i =1;i<=nbCol;i++){
            	  //Obtention du nom de la propriété à afficher
            	  String nom = rs.getMetaData().getColumnName(i);
            	  //Obtention de la valeur de la colonne
            	  String val = rs.getString(i);
            	  strb.append(" | ");
            	  strb.append(nom);
            	  strb.append(" : ");
            	  strb.append(val);
            	}
            	  //Affichage du nom et de la valeur
            	System.out.println(strb.toString());
            }
            //Fermeture des objets SQL
            rs.close();
            dbCon.close();
          }else{
            System.out.println("Paramètres insuffisants");
          }
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

|

Les procédures stockées : classe CallableStatement
    
    La classe java.sql.CallableStatement représente une procédure stockée dans le serveur
    de données.
    
    Syntaxe : 
    {call maProcedure[(?, ?, ...)]}
    {? = call maProcedure[(?, ?, ...)]} 
    La première syntaxe ne retourne pas de valeur.
    La seconde retourne une valeur.
    
    Méthode de la classe : 
    	Les méthodes de la classe CallableStatement sont les mêmes que pour les classes
    	PreparedStatement et ResultSet
    	La classe contient un ensemble de méthodes setXXX pour chaque types de données, 
    	qui permettent d'alimenter les paramètres de la procédure. 
    	La classe contient un ensemble de méthodes getXXX pour chaque types de données, 
    	qui permettent de récupérer le résultat de la procédure. 

    	Cependant il est possible de récupérer le résultat dans un ResultSet par la
    	méthode executeQuery().
    	
    	
Exercice : 


package formation.exercice;
 import java.sql.*;
    
 public class JDBCProcedureDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String parametre = args[0];
            //Déclaration du driver : 
            
            //Url de connexion 
            
            //Connexion à la BDD
            
            
            //Déclaration de la procédure AF4TOOL/DSPLIBL 
            
            //Alimentation du paramètre
            
            //Récupération du résultat
            
            //Boucler sur les enregistrements et afficher le résultat
            
            //Fermeture des objets SQL
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}
Corrigé

package formation.exercice;
 import java.sql.*;
    
 public class JDBCProcedureDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String parametre = args[0];
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400;naming=system;libraries=*LIBL"
            //Connexion à la BDD
            Connection dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //Déclaration de la procédure AF4TOOL/DSPLIBL
            String proc = "{call AF4TOOL/DSPLIBL()}";
            CallableStatement cstmt = null;
            try{
            	cstmt = dbCon.prepareCall(proc);
            }catch(SQLException se){
            	System.out.println(se.getMessage());
            }
            
            //Récupération du résultat
            ResultSet rs = cstmt.executeQery();
            //Boucler sur les enregistrements
            while(rs.next(){
            	  //Obtention des valeurs
            	System.out.println(rs.getString(1));
            }
            //Fermeture des objets SQL
            rs.close();
            cstmt.close();
            dbCon.close();
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}
      
      Il est aussi possible d'appeler des procédures stockées par l'intermédiaire de la	
      classe PreparedStatement.
      l'instruction call est un ordre standard SQL.

Même exemple avec appel par PreparedStatement.

      
package formation.exercice;
 import java.sql.*;
    
 public class JDBCProcedureDemo {

    public static void main(String[] args) {
       try{
          if(args.length>0){
            String parametre = args[0];
            //Déclaration du driver : 
            Class.forName("com.ibm.as400.access.AS400JDBCDriver");
            //Url de connexion 
            String dbUrl = "jdbc:as400://AS400;naming=system;libraries=*LIBL"
            //Connexion à la BDD
            Connection dbCon = DriverManager.getConnection(dbUrl,user,password);
            
            //Déclaration de la procédure AF4TOOL/DSPLIBL
            String proc = "call AF4TOOL/DSPLIBL(?)";
            PreparedStatement pstmt = null;
            try{
            	pstmt = dbCon.prepareStatement(proc);
            }catch(SQLException se){
            	System.out.println(se.getMessage());
            }
            
            //Récupération du résultat
            ResultSet rs = pstmt.executeQery();
            //Boucler sur les enregistrements
            while(rs.next(){
            	System.out.println(rs.getString(1));
            }
            //Fermeture des objets SQL
            rs.close();
            stmt.close();
            dbCon.close();
       }catch(Exception e){
         System.out.println(e.getMessage());
       }
    } 
}

©AF400