
Accès à des bases de données en JAVA |
| JDBC: Une API de haut niveau. Sun a développé une API en Java nommée JDBC (Java Database Connectivity) qui permet de se connecter à n'importe quelle BD et d'y faire des opérations grâce au langage de requêtes SQL. Cette API est générique, c-à-d qu'elle n'est pas liée à un SGDB particulier: elle permet aux applications "Client" d'accéder à n'importe quel type de SGDB et cela de manière transparente; par exemple, elle permet d'accéder de la même manière à une BD MSAccess, une BD Interbase, une BD Oracle,… En ce sens elle reprend la même idée qu' ODBC( OpenDatabase Connectivity) qui a été développée par Microsoft mais qui est une API en C, qui n'est pas orientée objet et qui assez difficile à utiliser (un peu comme une API native). Mais, un des gros avantages de JDBC par rapport à un produit comme ODBC (en dehors d'une programmation plus simple) est qu'une application écrite en Java avec JDBC fonctionne sur n'importe quel ordinateur doté d'une machine virtuelle Java(JVM) et cela en raison du byte-code neutre (indépendant de la plate-forme) généré par le compilateur Java. Comme ODBC, l'architecture de JDBC est formée de deux niveaux: . Une interface d'application (l'interface JDBC proprement dite) qui fait le lien entre l'application "client" Java et un gestionnaire de pilote (Driver Manager) et qui permet l'accès à une BD de façon indépendante du SGDB. . Une interface de pilote (L'API de pilote JDBC) qui sert d'interface entre le gestionnaire de pilote fournit par Java et les pilotes écrits par les différents éditeurs de SGDB; cette API de pilote définit les règles concernant l'écriture des pilotes spécifiques à chaque SGDB et n'a donc d'intérêt que pour les éditeurs de SGDB qui doivent fournir de tels pilotes s'ils veulent permettre l'accès à leurs BD via une application Java. L'API JDBC (qui est un ensemble d' interfaces Java) communique avec le gestionnaire de pilotes (Driver Manager); lors de la connexion à une BD, ce dernier va choisir le pilote associé à la BD et le charger; ensuite il va communiquer avec ce pilote via l'API de pilote JDBC. Il existe quatre types de pilotes JDBC: soit directs (pilotes de types 2, 3 et 4) qui se placent juste au dessus de l'interface native du SGDB, soit pontés ODBC (pilotes de type 1) • Pilote de type 1 qui traduit JDBC en ODBC (réalise un pont entre les deux protocoles) et se sert ensuite d'un pilote ODBC pour communiquer avec la BD. • Pilote de type 2 partiellement écrit en Java et partiellement écrit dans un langage natif et qui communique avec l'API cliente d'un SGDB. Avec ce type de pilote, il faut installer en plus de la bibliothèque Java des programme spécifiques dépendant de la plate-forme. • Pilote de type 3 est une bibliothèque entièrement écrite en Java qui se sert d'un protocole indépendant du SGDB et qui communique des requêtes SQL à un serveur intermédiaire (Middleware) qui lui-même se charge de traduire les requêtes dans un protocole propre à un SGDB particulier; on a ici typiquement affaire à un modèle C/S à trois niveaux. Interbase propose un tel pilote qui s'appelle InterClient et qui communique avec le serveur InterServer qui doit être installé et qui va communiquer avec le serveur Interbase. • Pilote de type 4 est une bibliothèque entièrement écrite en Java et qui traduit directement des requêtes SQL en un protocole spécifique au SGDB. La classe SQLException: La plupart des méthodes de l'API JDBC peuvent générer une exception de la classe SQLException. Cette exception contient des codes d'erreur et des messages décrivant le type de problèmes survenus; en fait un objet de cette classe est un genre de liste récursive dont les éléments sont eux-mêmes des objets de cette classe: pour parcourir et afficher tous les messages associés à une SQLException on appellera dans une boucle la méthode getNextException() de la classe SQLException qui retournera l'élément suivant de la liste(un nouvel objet de la classe SQLException) ou la valeur "null" si on est arrivé en fin de liste. Voici un exemple de méthode affichant tous les messages d'erreur: public static void showSQLException (java.sql.SQLException e) { java.sql.SQLException nextEx = e; while (nextEx != null) { System.out.println (nextEx.getMessage ()); System.out.println ("Error Code: " + nextEx.getErrorCode ()); System.out.println ("SQL State: " + nextEx.getSQLState ()); nextEx = nextEx.getNextException (); } } Principaux Concepts de Programmation JDBC: URL de Base de données: Paramètre d'une connection qui sert à localiser une BD et éventuellement d'autres paramètres. Elle est formée de trois parties séparées par ":": jdbc: La première partie est toujours jdbc. La deuxième est le sous protocole utilisé pour sélectionner le pilote spécifique qui sera chargé d'établir une connexion, à un BD. La troisième contient une information qui localise la BD plus d'éventuels paramètres de connexion comme un login ou/et un password. Donnons des exemples d'URL de BD: jdbc:odbc:DbDemos Permet de se connecter à une BD associée à une source de données ODBC DbDemos définit sur la machine locale. Jdbc:interbase://5323/D:/Apublic/Revue.gdb Permet de se connecter à la BD Revue.gdb Interbase via le serveur InterServer situé sur la machine 5323; la BD se trouve dans le sous-répertoire Apublic du drive D. Chargement et enregistrement de la classe associée à un pilote JDBC: Avant de réaliser une connection à une BD une classe implémentant l'interface Driver devra être chargée par la JVM et enregistrée au près du DriverManager; ce dernier au moment d'établir une connection choisira le Driver associé au sous-protocole de L'URL de BD. Si ce driver n'est pas trouvé, une erreur surviendra et aucune connection ne pourra être établie. Il existe plusieurs façons de charger et d'enregistrer un driver: • La façon la plus simple et la plus directe est la suivante: On appelle la méthode "static" forName() de la classe Class comme suit: Class.forName("DriverClassName"); Cette méthode va essayer de charger la classe dont le nom est mentionné comme paramètre et ensuite initialiser cette classe: Les clauses "static" d'initialisation de la classe vont être exécutées et vont créer une instance de la classe (qui doit implémenter l'interface Driver) et enregistrer cette instance auprès du DriverManager; (Cela fait partie des spécifications de tout JDBC Driver). Cette alternative est indépendante du driver. Si la classe n'est pas trouvée une exception de type ClassNotFoundException sera générée. • Une autre façon de charger un ou plusieurs drivers est d'initialiser la propriété "system" jdbc.drivers avec une chaîne de caractères représentant une liste des noms de classes associées à différent drivers, les noms seront séparés par le caractère ':' (deux points). On peut par exemple définir un fichier (texte) de propriétés qui contiendra série de lignes de structure: Parmi ces propriétés on aura la propriété jdbc.drivers mais on pourra aussi ajouter des propriétés représentant des paramètres de connexion comme un "login", un mot de passe,etc…etc… Voici un exemple d'un tel fichier: jdbc.drivers=sun.jdbc.odbc.JdbcOdbcDriver:interbase.interclient.Driver user=SYSDBA password=masterkey Voici un exemple de code permettant de lire ce fichier et de charger les drivers mentionnés dans la propriété et de définirl'URL de BD, le login et le mot de passe: Properties dbProps = new Properties(); // Crée un nouvel objet de la classe Properties. FileInputStream in = new FileInputStream(PropertiesFileName); dbProps.load(in); // Charge les propriétés à partir du flux d'entrée in String drivers = dbProps.getProperty("jdbc.drivers"); // Extrait la propriété jdbc.drivers if (drivers!=null) // Si cette propriété a été définie, on l'ajoute aux propriétés "system". System.setProperty("jdbc.drivers",drivers); String urlDb = dbProps.getProperty("jdbc.url"); // Extrait l'URL de BD. String user = dbProps.getProperty("jdbc.username"); // Extrait le username. String password = dbProps.getProperty("jdbc.password"); // Extrait le mot de passe. • Une techique plus récente (pour charger un driver et l'enregistrer) consiste à utiliser une interface de repértoires et de noms JAVA (JAVA Naming Directory Interface = JNDI) et une interface DataSourcec. L'emplacement des sources de données sera normalement géré dans un même répertoire et le service JNDI permet de repèrer une source de données et de retourner un objet implémentant l'interface DataSource. Avec cet objet on peut obtenir une connexion à une BD sans passer par le DriverManager. On aura par exemple le code suivant: Context jndiContext = …; DataSource dsrc = (DataSource)jndiContext.lookup("jdbc/unRep/…"); Connection con = dsrc.getConnection(username,passwd); On peut aussi parfois obtenir un objet DataSource en appelant directement un constructeur qui est fourni avec la librairie associée à un driver spécifique; par exemple avec le driver interclient d' Interbase on aura le code suivant: DataSource dsrc = new interbase.interclinet.DataSource(); Obtenir une connexion à une base de données: (Interface Connection): Avant de manipuler une BD, il faut comme toujours se connecter à cette BD; pour réaliser cela, il faut obtenir un objet qui implémente l'interface Connection grâce à une méthode getConnection(). La classe DriverManager possède les deux méthodes "static" suivantes pour faire cela: static Connection getConnection(String urlDb, String userName, String passwd) qui essaie d'établir une connexion avec la Bd avec les paramètres de connexion urlDb, userName, passwd. static Connection getConnection(String urlDb, Properties props) qui essaie d'établir une connexion avec la Bd avec les paramètres de connexion suivants: urlDb qui représente l'URL de la BD et props qui représente un objet de la classe Propreties qui contient au minimum les couples (clé/valeur) user=userName et password=passwd. On peut aussi obtenir une connexion à l'aide d'un objet implémentant l'interface DataSource (voir plus haut) ou encore en appelant directement la méthode connect(urlDb, props) d'un objet représentant un driver spécifique mais cette dernière technique est dépendante du driver. L'interface Connection permet d'obtenir des renseignement sur la BD à laquelle on est connectée, de gérer les transactions et d'appeler des procédures stockées mais son rôle le plus courant est bien sûr de créer des objets Statement ou PreparedStatement pour pouvoir exécuter des requêtes SQL. La méthode getMetaData() fournit des renseignements sur mes méta-données de la BD (elle est détaillée plus bas). Les méthodes commit(), rollback() terminent la transaction en cours soit en la validant, soit en annulant toutes les actions réalisées dans son cadre. La méthode setAutoCommit(boolean mode) positionne le mode auto-commit; si ce mode vaut true (ce qui est la valeur par défaut), chaque instruction SQL exécutée est considèrée comme une transaction individuelle et est automatiquement validée. Si on veut regrouper plusieurs instructions SQL dans une transaction, il faut mettre ce mode à false et terminer la transaction par un commit() ou un rollback(). Les méthodes int getTransactionIsolation() et void setTransactionIsolation(int niveau) permettent respectivement d'obtenir le niveau d'isolation de la connexion ou de fixer ce niveau. La méthode void close() ferme la connexion courante. Créer un objet Statement ou PreparedStatement: Une fois la connexion établie, il faut obtenir un objet implémentant soit l'interface Statement, soit l'interface PreparedStatement. Ces objets encapsulent soit une instruction SQL non préparée, soit une instruction SQL préparée (c'à-d compilée par le serveur de Bd). Ces objets sont obtenus à l'aide des méthodes (de l'interface Connection) suivantes: Statement CreateSatement(), PreparedStatement prepareStatement("Un instruction SQL"). Par exemple on aura le code suivant: Connexion con = DriverManager.getConnection(urlDb, "SYSDBA", "masterkey"); Statement stmt = con. CreateSatement(); PreparedStatement pstmt = con.prepareStatement("Select * from Livres Where Auteur=?";); Exécuter une requête SQL: Comme d'habitude, il faut distinguer plusieurs cas selon que: • La requête retourne un ensemble de valeurs (comme un SELECT) ou non (comme un INSERT, DELETE, UPDATE, CREATE….). • La requête est préparée ou non. • Cas d'une requête non préparée ne retournant rien: On appelle dans ce cas la méthode int executeUpdate("Requête") sur un objet Statement: Par exemple on aura: int n = stmt.executeUpdate("INSERT INTO REVUE VALUES (3, 'DB Journal', 'Info'"); Cette méthode retourne le nombre de lignes modifiées dans la table par la requête. • Cas d'une requête préparée ne retournant rien: En général, ce genre de requête contient des paramètres qui doivent être initialisés juste avant l'exécution de la requête. Pour initialiser ces paramètres on appellera une méthode: setXxx(int parIndex, Xxx valeur) de la classe PreparedStatement. Ici parIndex représente l'indice du paramètre (1,2,3,…), valeur représente la valeur associée et Xxx un type de base comme (int, double, String,…). On appellera ensuite la méthode int executeUpdate() sur un objet PreparedStatement et cette méthode retournera le nombre de lignes modifiées dans la table. Par exemple on aura: PreparedStatement pstmt = con.prepareStatement("Delete from Livres Where Auteur=?";); pstmt.setString(1,"Camus"); int n = pstmt.executeUpdate(); • Cas d'une requête non préparée retournant un ensemble de lignes: (Interface ResultSet) C'est le cas d'un "SELECT" sans paramètre. On appellera la méthode executeQuery(String requeteSelect) sur un objet Statement qui retourne un objet implémentant l'interface ResultSet; un tel objet encapsule la collection (éventuellement vide) des lignes retournées par la requête, chaque ligne étant elle-même un tableau de colonnes indicé soit par un entier commençant à 1 (1, 2, 3…) soit par le nom de la colonne (une String). Un objet ResultSet maintient un curseur sur la ligne courante et pour passer à la ligne suivante il faut appeler la méthode next() définie dans l'interface ResultSet: cette méthode next() retourne un booléen; plus précisèment, elle retourne la valeur true s'il y a encore des lignes à parcourir sinon elle retournera la valeur false (quand il n'y a plus de ligne suivante). Attention, au départ le curseur est positionné avant la première ligne et par conséquent, il faudra d'abord appeler la méthode next() pour accèder à cette première ligne. Typiquement on utilisera une boucle while (rs.next()) pour parcourir l'ensemble des lignes. Pour retrouver la valeurs des colonnes de chaque ligne l'interface ResultSet a défini des méthodes getXxx(int colIndex) où la colonne est repèrée par un indice entier >0 ou getXxx(String colName) où la colonne est repèrée par son nom (Ici, Xxx représente un type de base comme int, double, boolean, String,…). Pour obtenir des renseignements sur les colones associées à un ResultSet, il faut appeler la méthode getMetaData() de l'interface ResultSet qui va retourner un objet implémentant l'interface ResultSetMetaData; cette dernière interface fournit des méthodes telles que getColumnCount()( retourne le nombre de colonnes du ResultSet associé), getColumName(int i) (Retourne le nom de la colonne d'indice i du ResultSet associé), getColumTypeName(int i) (Retourne le type de la colonne d'indice i du ResultSet associé),… Pour plus détail sur cette interface, voir plus bas. Donnons un exemple: affichage des lignes retournées par une requête SELECT. ResultSet rs = stmt.executeQuery("SELECT * from Client"); ResultSetMetData rsmdta = rs.getMetaData(); while ( rs.next() ) { for (int i =1; i<=rsmdta.getColumnCount(); i++) System.out.print(rs.getString(i)+" "); System.out.println(); } • Cas d'une requête préparée retournant un ensemble de lignes: (Interface ResultSet) Il s'agit normalement d'une requête SELECT paramètrée. Comme dans le deuxième cas, la requête doit être préparée avec prepareStatement(String requete) qui va fournir un objet PreparedStatement. On passe ensuite les paramètres effectifs à l'objet PreparedStatement à l'aide des méthodes setXxx(int colIndex, Xxx valeur) et on appelle après la méthode executeQuery() qui va retourner comme dans le cas précédent un ResultSet qu'on traitera de la même manière. Donnons un petit exemple: PreparedStatement pstmt = con.prepareStatement("Select from Livres Where Auteur=? And Prix < ?";); pstmt.setString(1,"Camus"); pstmt.setInt(2, 20); ResultSet rs = pstmt.executeQuery(); // la suite du traitement est identique au cas précédent. Attention : Il ne faut pas appeler deux fois de suite une méthode getXxx(int indexColumn) avec le même indice de colonne sur la ligne courante ; quand c’est nécessaire, il faut sauver dans une variable la valeur retournée par le premier getXxx(int indexColumn) et réutiliser cette valeur quand on en a besoin Pour savoir si la valeur de la dernière colonne qui vient d’être lue (par un getXxx(i)) est nulle (NULL) il faut appeler juste après le getXxx(i) la méthode boolean wasNull() de l'interface ResultSet, méthode qui retournera true ssi la valeur de la colonne était NULL. Extraction des méta-données d'une BD: Interface DatabaseMetaData: Cette interface définit des méthodes qui permettent d'obtenir des renseignements sur la structure d'une base de données (méta-données) à laquelle on est connecté tels que le nom des tables, des vues, des procédures stockées,…, le nom, le type des colonnes, les clés primaires et étrangères de chaque table, etc..etc… Beaucoup de ces méthodes retournent un ResultSet, c'à-d un ensemble de résultat(en fait, une table) dont on pourra parcourir les différentes lignes à l'aide de la méthode next() et extraire la valeur de chaque colonne à l'aide des méthodes getXxx(String colName) où Xxx désigne un type JAVA comme String, int, double,… Certaines méthodes ont des arguments qui correspondent à des "String patterns", c'à-d, à des modèles de String; par exemple, "%" représente n'importe quelle String, "_" représente n'importe quelle String de un caractère. Certaines méthodes ont des arguments qui représentent le nom d'un catalogue et d'un schéma. Que représentent ces deux concepts? Un schéma décrit un groupe de tables associées et des droits d'accès alors qu'un catalogue décrit un groupe de schéma associés. Ces concepts sont importants pour structurer de grandes bases de données mais ne sont pas définis pour tous les SGDB; dans ce dernier cas, on remplacera ces paramètres par une chaîne vide ("") ou par la valeur null; un chaîne vide signifiera que la méthode va retourner des informations non liées à un catalogue ou un schéma alors que la valeur null signifiera que la méthode va retourner des informations indépendamment d'un catalogue ou d'un schéma. L'obtention d'un objet implémentant cette interface s'obtient en appelant la méthode getMetaData() de l'interface Connection; on aura par exemple le code suivant: DatabaseMetadata metaData = con.getMetaData(); // Ici con est un objet de type Connection. Les méthodes de cette interface peuvent générer des exceptions de la classe SQLException. Voici un résumé des principales méthodes de cette interface: Obtenir le nom des tables, des vues d'une BD: ResultSet getTables ( String catalog, String schemaPattern, String tableNamePattern, String[] types) Cette méthode retourne dans un ResultSet des informations sur toutes les tables associées à un catalogue, à un pattern de schéma, à un pattern de nom de table et à un ensemble de types de tables. Les types les plus courants sont "TABLE", "VIEW", "SYSTEM TABLE". Le ResultSet retourné contient les 5 colonnes suivantes de type String: 1 TABLE_CAT Catalogue du table. 2 TABLE_SCHEM Schéma de la table. 3 TABLE_NAME Nom de la table. 4 TABLE_TYPE Type de la table. 5 REMARKS Remarques sur la table. Voici un exemple qui affiche toutes les tables et vues dont le nom débute par "C": ResultSet tableNames = metaData.getTables (null, null, "C%", new String[] "TABLE","VIEW"}); while ( tableNames.next () ) System.out.println ( tableNames.getString ("TABLE_NAME")+ "[" + tableNames.getString ("TABLE_TYPE ")+"]" ); tableNames.close (); Obtenir des informations sur les colonnes d'une table ou d'une vue: ResultSet getColumns (String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) Cette méthode retourne dans un ResultSet des informations sur toutes les colonnes associées à un catalogue, à un pattern de schéma, à un pattern de nom de table et à un pattern de nom de colonne. Le ResultSet retourné contient 18 colonnes dont les principales sont les suivantes: 3 TABLE_NAME Nom de la table. 4 COLUMN_NAME Nom de la colonne. 6 TYPE_NAME Nom du type de la colonne. 7 COLUMN_SIZE (int) Taille de la colonne. 9 DECIMAL_DIGITS (int) Nombre de décimales après la virgule. 18 IS_NULLABLE La colonne admet des valeurs nulles? La colonne COLUMN_SIZE représente pour les types CHAR, VARCHAR ou DATE le nombre maximum de caractères et pour les types NUMERIC et DECIMAL leur précision. La colonne IS_NULLABLE retourne la String "YES" si la colonne admet des valeurs nulles sinon elles retourne "NO"; si on ne sait pas(!!), elle retourne la string null. Voici un exemple qui affiche toutes les colonnes ( nom, type, taille, valeur Null?) de la table CLIENT: ResultSet cols = metaData.getColumns ("", "" , "CLIENT" , "%"); System.out.println ("Voici colonnes de la table CLIENT:"); System.out.println("NOM"+"\t"+"TYPE"+"\t"+"TAILLE"+"\t"+"NULL?"); while (cols.next ()) { System.out.println(cols.getString("COLUMN_NAME") + "\t" +cols.getString("TYPE_NAME") + "\t" +cols.getString("COLUMN_SIZE") + "\t" +cols.getString ("IS_NULLABLE")); } cols.close (); Obtenir la clé primaire d'une table: ResultSet getPrimaryKeys (String catalog, String schemaPattern, String TableName) Cette méthode retourne dans un ResultSet des informations sur la clé primaire d'une table associée à un catalogue et à un pattern de schéma. Le ResultSet retourné contient 6 colonnes dont les principales sont les suivantes: 3 TABLE_NAME Nom de la table. 4 COLUMN_NAME Nom de la colonne faisant partie de la clé primaire. 6 PK_NAME Nom de la clé primaire (null si pas définie). Voici un exemple qui affiche toutes les colonnes constituants la clé primaire de la table ARTICLE: ResultSet pk = metaData.getPrimaryKeys("", "", "ARTICLE"); System.out.println("Cle Primaire de la table ARTICLE: "); while (pk.next()) System.out.print(pk.getString("COLUMN_NAME")+" "); pk.close (); Pour obtenir les clés étrangères d'une table: ResultSet getImportedKeys (String catalog, String schemaPattern, String TableName) Cette méthode retourne dans un ResultSet des informations sur la ou les clé(s) étrangère(s) d'une table associée à un catalogue et à un pattern de schéma. Le ResultSet retourné contient 14 colonnes dont les principales sont les suivantes: 3 PKTABLE_NAME Nom de la table à laquelle la clé étrangère fait référence. 4 PKCOLUMN_NAME Nom de la colonne associée à clé primaire référencée. 8 FKCOLUMN_NAME Nom de la colonne associée à la clé étrangère. 10 UPDATE_RULE(short) Type d'action lors d'un Update. 11 DELETE_RULE(short) Type d'action lors d'un Delete. 12 FKCOLUMN_NAME Nom de la clé étrangère (peut être null). 13 PKCOLUMN_NAME Nom de la clé primaire référencée (peut être null). Les colonnes UPDATE_RULE et DELETE_RULE précisent l'action à entreprendre en cas de modification ou de suppression de la clé primaire qui est référencée par la clé étrangère. Les valeurs possibles de ces colonnes sont les constantes de type short suivantes: DatabaseMetaData.importedKeyCascade, DatabaseMetaData.importedKeySetNull, DatabaseMetaData.importedKeySetDefault, DatabaseMetaData.importedKeyNoAction L'action associée à chacune de ces constantes est évidente. (leur nom est suffisamment parlant). Ces constantes seront typiquement testées dans une instruction "switch… case ". Voici un exemple qui permet d'obtenir les clés étrangères de la table ECRIT: ResultSet fks = metaData.getImportedKeys("", "", "ECRIT"); System.out.println("FOREIGN KEYS de la table ECRIT:"); while ( fks.next(.) ) { System.out.print( fks.getString("FKCOLUMN_NAME")+" REFERENCES " + fks.getString("PKTABLE_NAME") + "(" + fk.getString("PKCOLUMN_NAME") + ")" ); } fks.close (); L'interface DatabaseMetaData contient une centaine d'autres méthodes qui permettent d'obtenir d'autres renseignements sur une BD tels que le nom et la description des procédures stockées, la longueur maximale du nom des tables et des colonnes, la description des types standard SQL supportés par la BD, etc…etc. Consultez les fichiers HTML de la "doc" (répertoire D:/jdk1.3/docs) pour avoir plus de détail. Interface ResultSetMetaData: Cette interface définit des méthodes qui permettent d'obtenir des renseignements sur la structure des données retournées par l'exécution d'une requête SELECT dans un ensemble de données (objet qui implémente l'interface ResultSet); typiquement, on peut retrouver le nom, le type, la taille ainsi que le nombre de colonnes retournées. Pour obtenir un objet implémentant cette interface on appellera la méthode getMetaData() appliquée à un objet ResultSet retourné par l'exécution d'une requête On aura le code suivant: ResultSet rs = con.executeQuery("SELECT ….FROM…."); ResultSetMetaData rsmdta = rs.getMetaData(); Voici les principales méthodes de cette interface: int getColumnCount() // Retourne le nombre de colonnes du ResultSet // associé. String getColumnName(i) // Retourne le nom de la colonne n°i. String getColumnLabel(i) // Retourne le titre (affiché) de la colonne n°i. String getColumnTypeName(i) // Retourne le nom du type de la colonne n°i. int getColumnDisplaySize(i) // Retourne la largeur maximale en caractères de la // colonne n°i. int getPrecision(i) // Retourne le nombre de digits décimaux de la // colonne n°i. int getColumnType(i) // Retourne le type de la colonne n°i selon la classe // java.sql.Types qui contient des.déclarations de // constantes(int) correspondant aux types SQL. int getScalet(i) // Retourne le nombre de digits décimaux à droite du // point décimal de la colonne n°i. int isNullable(i) // Permet de savoir si la colonne n°i admet des valeurs // nulles; les valeurs possibles retournées sont les // constantes entières: columnNoNulls, columnNullable // et columnNullableUnknown NB: Les indices de colonnes commencent à 1 et vont jusqu'à getColumnCount(). Les méthodes de cette interface peuvent générer des exceptions de la classe SQLException. |