FAQ JDBCConsultez toutes les FAQ

Nombre d'auteurs : 8, nombre de questions : 162, dernière mise à jour : 3 juin 2015  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.


SommaireLes métadonnées - MetaDataGénéralités et informations sur le SGBD (11)
précédent sommaire suivant
 

Les métadonnées sont les informations, accessibles via JDBC, sur une base de données ou sur le résultat d'une requête SQL. Ce sont en fait les informations accessibles en dehors des données elles-mêmes. Les métadonnées sont gérées par plusieurs classes :

  • DatabaseMetaData : informations sur la base de données dans son ensemble. Récupérable avec la méthode getMetaData de Connection ;
  • ResultSetMetaData : informations sur les types et propriétés des colonnes d'un ResultSet. Récupérable avec la méthode getMetaData de ResultSet ou de PreparedStatement ;
  • ParameterMetaData : informations sur les paramètres des objets PreparedStatement. Récupérable avec la méthode getParameterMetaData de PreparedStatement.

Toutes ces interfaces font partie du package java.sql. On peut aussi noter l'existence de RowSetMetaData dans le package javax.sql.

Mis à jour le 11 avril 2013 Ioan

Pour obtenir ces informations, on peut utiliser l'interface DatabaseMetaData. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
Connection connection = DriverManager.getConnection(url,user,password); 
  
//on récupère les métadonnées à partir de la connexion 
DatabaseMetaData dmd = connection.getMetaData(); 
  
//récupération des informations 
String nomBase = dmd.getDatabaseProductName(); 
String versionBase = dmd.getDatabaseProductVersion(); 
  
//affichage des informations 
System.out.println("Nom de la base = "+nomBase); 
System.out.println("Version de la base = "+versionBase);
Vous pouvez aussi utiliser les méthodes getDatabaseMinorVersion() et getDatabaseMajorVersion().

Mis à jour le 11 avril 2013 Ioan

La liste des catalogues du SGBD et le terme employé par celui-ci pour désigner un catalogue peuvent être obtenus grâce à DatabaseMetaData.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
Connection connection = DriverManager.getConnection(url,user,password); 
//on récupère les métadonnées à partir de Connection 
DatabaseMetaData dmd = connection.getMetaData(); 
//récupération des informations 
String catalogTerm = dmd.getCatalogTerm(); 
ResultSet resultat = dmd.getCatalogs(); 
//affichage des informations 
System.out.println("Terme du SGBD pour catalogue = "+catalogTerm); 
while(resultat.next()){ 
   String nomCatalog = resultat.getString("TABLE_CAT"); 
   System.out.println(catalogTerm+" "+resultat.getRow()+ " = "+nomCatalog); 
}

Mis à jour le 11 avril 2013 Ioan

Une des principales difficultés, lors de l'utilisation de l'API JDBC, est de se retrouver parmi les différentes versions des drivers, des SGBD ou de la spécification JDBC elle-même. Heureusement, DatabaseMetaData permet d'accéder facilement à partir du programme à plusieurs de ces informations. Cela permet de rendre les programmes utilisant cette API le plus indépendants possible, par rapport aux SGBD ou aux implémentations des Drivers. Voici quelques exemples :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void getInformationsSQL(Connection connection) throws SQLException{ 
   DatabaseMetaData dmd = connection.getMetaData(); 
   System.out.println("Supporte la norme ANSI92 (niveau d'entrée) = " 
                               +dmd.supportsANSI92EntryLevelSQL()); 
   System.out.println("Supporte la norme ANSI92 (niveau intermédiaire) = " 
                               +dmd.supportsANSI92IntermediateSQL()); 
   System.out.println("Supporte complètement la norme ANSI92 = " 
                               +dmd.supportsANSI92FullSQL()); 
   System.out.println("Supporte la grammaire SQL ODBC minimum = " 
                               +dmd.supportsMinimumSQLGrammar()); 
   System.out.println("Supporte la grammaire SQL ODBC = " 
                               +dmd.supportsCoreSQLGrammar()); 
   System.out.println("Supporte la grammaire SQL ODBC étendue = " 
                               +dmd.supportsExtendedSQLGrammar()); 
   System.out.println("Supporte GROUP BY = " 
                               +dmd.supportsGroupBy()); 
   System.out.println("Supporte SELECT FOR UPDATE = " 
                               +dmd.supportsSelectForUpdate()); 
}
Bien d'autres informations sont accessibles, il ne vous reste qu'à fouiller dans la javadoc ;-).

Mis à jour le 11 avril 2013 Ioan

La méthode getTypeInfo de DatabaseMetaData renvoie un ResultSet contenant des informations sur les types SQL supportés par le SGBD.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
Connection connection = DriverManager.getConnection(url,user,password); 
DatabaseMetaData dmd = connection.getMetaData(); 
ResultSet types = dmd.getTypeInfo(); 
while(types.next()){ 
   System.out.println("###################################"); 
   for(int i=0; i<types.getMetaData().getColumnCount();i++){ 
      String nomColonne = types.getMetaData().getColumnName(i+1); 
      Object valeurColonne = types.getObject(i+1); 
      System.out.println(nomColonne+" = "+valeurColonne); 
   } 
}
Pour mieux comprendre les informations retournées, voici une partie des noms, types et significations des colonnes de ce ResultSet.

  • TYPE_NAME String = nom du type
  • DATA_TYPE int = valeur entière correspondante dans java.sql.Types
  • PRECISION int = précision maximum
  • LITERAL_PREFIX String = préfixe utilisé pour entourer les chaînes de caractères
  • LITERAL_SUFFIX String = suffixe utilisé pour entourer les chaînes de caractères
  • CREATE_PARAMS String = paramètres utilisés lors de la création du type
  • NULLABLE short = possibilité d'être NULL (cf. variables statiques de DatabaseMetaData)
  • CASE_SENSITIVE boolean = indique si le type est sensible à la casse
  • SEARCHABLE short = indique la possibilité d'utiliser ce type dans les clauses WHERE
  • UNSIGNED_ATTRIBUTE boolean = indique si le type est non signé
  • FIXED_PREC_SCALE boolean = indique si le type peut être utilisé comme valeur monétaire
  • AUTO_INCREMENT boolean = indique si le type peut être utilisé pour une valeur auto-incrémentée
  • LOCAL_TYPE_NAME String = nom du type correspondant à la locale

Revenons sur NULLABLE short
  • typeNoNulls - ne peut pas être NULL
  • typeNullable - peut être NULL
  • typeNullableUnknown - aucune information disponible

Revenons sur SEARCHABLE short
  • typePredNone - non
  • typePredChar - seulement dans les clauses WHERE .. LIKE
  • typePredBasic - pour toutes les clauses sauf WHERE .. LIKE
  • typeSearchable - pout tout type de clause WHERE

On peut donc cibler notre recherche selon ces colonnes. Par exemple, pour ne récupérer que le nom des types, on peut faire comme ceci :

Code java : Sélectionner tout
1
2
3
4
5
6
7
Connection connection = DriverManager.getConnection(url,user,password); 
DatabaseMetaData dmd = connection.getMetaData(); 
ResultSet types = dmd.getTypeInfo(); 
while(types.next()){ 
   String nomType = types.getString("TYPE_NAME"); 
   System.out.print(nomType+" "); 
}
Voici le résultat pour MySQL :

BIT BOOL TINYINT BIGINT LONG VARBINARY MEDIUMBLOB LONGBLOB BLOB TINYBLOB VARBINARY BINARY LONG VARCHAR MEDIUMTEXT LONGTEXT TEXT TINYTEXT CHAR NUMERIC DECIMAL INTEGER INT MEDIUMINT SMALLINT DOUBLE FLOAT DOUBLE DOUBLE PRECISION REAL VARCHAR ENUM SET DATE TIME DATETIME TIMESTAMP

Pour retrouver les UDT (User Defined Type), on peut utiliser la méthode getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) (cf. javadoc pour l'utilisation de cette méthode).

Mis à jour le 11 avril 2013 Ioan

Cette liste est obtenue grâce à la méthode getSQLKeywords de DatabaseMetaData. Cette méthode renvoie une seule chaîne de caractères (String) dans laquelle les différents mots clefs sont séparés par une virgule. Par mots clefs SQL non standard, on entend les mots clefs n'appartenant pas à la norme SQL92.

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static String[] getMotsNonStandard(Connection connection) throws SQLException{ 
   DatabaseMetaData dmd = connection.getMetaData(); 
   return dmd.getSQLKeywords().split(","); 
} 
public static void main(String[] args){ 
   try{ 
      String driver = args[0]; 
      Class.forName(driver); 
      String url = args[1]; 
      String user = args[2]; 
      String password = args[3]; 
      Connection connection = DriverManager.getConnection(url,user,password); 
      String[] mots = getMotsNonStandard(connection); 
      for(int i=0;i<mots.length;i++){ 
          System.out.println(mots[i]); 
      } 
   }catch(SQLException sqle){ 
      //... 
   }catch(Exception e){ 
      //... 
   } 
}
Pour MySQL, l'exécution de cet exemple donne :

Code text : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
AUTO_INCREMENT 
BINARY 
BLOB 
ENUM 
INFILE 
LOAD 
MEDIUMINT 
OPTION 
OUTFILE 
REPLACE 
SET 
TEXT 
UNSIGNED 
ZEROFILL

Mis à jour le 11 avril 2013 Ioan

Ces différentes listes sont accessibles depuis la classe DatabaseMetaData.

  • getStringFunctions() : retourne une chaîne de caractères contenant les noms des fonctions travaillant sur les chaînes de caractères.
  • getNumericFunctions() : retourne une chaîne de caractères contenant les noms des fonctions travaillant sur les nombres.
  • getSystemFunctions() : retourne une chaîne de caractères contenant les noms des fonctions système.
  • getTimeDateFunctions() : retourne une chaîne de caractères contenant les noms des fonctions travaillant sur le temps (TIME, TIMESTAMP ou DATE).

Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
public static ArrayList getAllFunctions(Connection connection) throws SQLException{ 
   ArrayList liste = new ArrayList(); 
   DatabaseMetaData dmd = connection.getMetaData(); 
   String[] tab = dmd.getStringFunctions().split(","); 
   liste.addAll(Arrays.asList(tab)); 
   tab = dmd.getNumericFunctions().split(","); 
   liste.addAll(Arrays.asList(tab)); 
   tab = dmd.getSystemFunctions().split(","); 
   liste.addAll(Arrays.asList(tab)); 
   tab = dmd.getTimeDateFunctions().split(","); 
   liste.addAll(Arrays.asList(tab)); 
   return liste; 
}
Code java : Sélectionner tout
1
2
3
4
5
Connection connection = DriverManager.getConnection(url,user,password); 
ArrayList liste = getAllFunctions(connection); 
for(Iterator it = liste.iterator();it.hasNext();){ 
   System.out.println(it.next()); 
}

Mis à jour le 11 avril 2013 Ioan

L'accès à cette information se fait grâce à DatabaseMetaData et grâce à la méthode getProcedures. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Connection connection = DriverManager.getConnection(url,user,password); 
DatabaseMetaData dmd = connection.getMetaData(); 
ResultSet procedures = dmd.getProcedures(connection.getCatalog(),null,"%"); 
while(procedures.next()){ 
   System.out.println("######################################"); 
   String nom = procedures.getString("PROCEDURE_NAME"); 
   int type = procedures.getInt("PROCEDURE_TYPE"); 
   String sType = ""; 
   switch(type){ 
      case DatabaseMetaData.procedureResultUnknown : 
         sType = "peux renvoyer un résultat"; 
         break; 
      case DatabaseMetaData.procedureNoResult : 
          sType = "ne renvoie pas de résultat"; 
          break; 
      case DatabaseMetaData.procedureReturnsResult : 
          sType = "retourne obligatoirement un résultat"; 
          break; 
      default : sType = "type inconnu";break; 
   } 
   System.out.println("Nom ("+dmd.getProcedureTerm()+") = "+nom); 
   System.out.println("Type = "+sType); 
}
Dans cet exemple, on passe % comme paramètre de recherche sur le nom, ce qui a pour effet de rechercher toutes les procédures.

Mis à jour le 11 avril 2013 Ioan

La méthode getProcedureColumns de DatabaseMetaData permet d'avoir accès aux informations relatives à une ou plusieurs procédures stockées. Cette méthode renvoie un ResultSet dont chaque ligne décrit un paramètre ou une colonne de la procédure. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public static void main(String[] args){ 
   try{ 
      Class.forName("nom.du.Driver").newInstance(); 
      String url = "jdbc:..."; 
      String user = "user"; 
      String password = "pass"; 
      Connection connection = DriverManager.getConnection(url,user,password); 
      //recherche d'informations sur tous les paramètres de la procèdure "hello" 
      getInformations(connection, "hello"); 
   }catch(SQLException sqle){ 
      //etc. 
   } 
} 
public static void getInformations(Connection connection, String nomProcedure) throws SQLException{ 
DatabaseMetaData dmd = connection.getMetaData(); 
ResultSet infos = dmd.getProcedureColumns(connection.getCatalog(), 
                              null,nomProcedure,"%"); 
    while(infos.next()){ 
       System.out.println("##############"); 
       System.out.println("Nom parametre = "+infos.getString("COLUMN_NAME")); 
       System.out.println("Type paramètre = "+getType(infos.getInt("COLUMN_TYPE"))); 
       System.out.println("Type SQL = "+infos.getString("TYPE_NAME")); 
    } 
infos.close(); 
} 
public static String getType(int type){ 
   String sType = ""; 
   switch(type){ 
      case DatabaseMetaData.procedureColumnUnknown : 
         sType = "inconnu"; 
         break; 
      case DatabaseMetaData.procedureColumnIn : 
         sType = "IN"; 
         break;  
      case DatabaseMetaData.procedureColumnInOut : 
         sType = "INOUT"; 
         break; 
      case DatabaseMetaData.procedureColumnOut : 
         sType = "OUT"; 
         break; 
      case DatabaseMetaData.procedureColumnReturn : 
         sType = "valeur de retour"; 
         break; 
      case DatabaseMetaData.procedureColumnResult : 
         sType = "résultat de la requête"; 
         break; 
      default : sType = "";break;  
   } 
   return sType; 
}
On peut naturellement utiliser cette méthode comme getTables pour vérifier l'existence d'une procédure stockée, ou d'un paramètre bien précis.

Mis à jour le 11 avril 2013 Ioan

DatabaseMetaData permet de connaître certains maximums imposés par le SGBD. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
public static void getMaximumsDonnees(Connection connection) throws SQLException{ 
   DatabaseMetaData dmd = connection.getMetaData(); 
   System.out.println("Maximum de colonnes dans une table = " 
                               +dmd.getMaxColumnsInTable()); 
   System.out.println("Taille max. d'un index = " 
                               +dmd.getMaxIndexLength()); 
   System.out.println("Taille max. d'une ligne = " 
                               +dmd.getMaxRowSize()+ 
                               " (blobs inclus = "+dmd.doesMaxRowSizeIncludeBlobs()+")"); 
   System.out.println("Taille max. d'une chaîne de caractères = " 
                               +dmd.getMaxCharLiteralLength()); 
}
Il existe une vingtaine de méthodes getMaxXXX dans l'interface DatabaseMetaData. Vous n'avez plus qu'à fouiller dans la javadoc ;-)

Mis à jour le 11 avril 2013 Ioan

DatabaseMetadata permet de récupérer plusieurs informations sur le pilote utilisé par une instance de Connection. Par exemple :

Code java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Connection connection = DriverManager.getConnection(url,user,password); 
  
//on récupère les métadonnées à partir de la connexion 
DatabaseMetaData dmd = connection.getMetaData(); 
  
//récupération des informations 
String nomDriver = dmd.getDriverName(); 
String versionDriver = dmd.getDriverVersion(); 
String vMajeureJDBC = dmd.getJDBCMajorVersion(); 
String vMineureJDBC = dmd.getJDBCMinorVersion(); 
  
//affichage des informations 
System.out.println("Nom du driver utilisé = "+nomDriver); 
System.out.println("Version du driver = "+versionDriver); 
System.out.println("Version JDBC supportée par le driver = "+vMajeureJDBC+"."+vMineureJDBC);

Mis à jour le 11 avril 2013 Ioan

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsables bénévoles de la rubrique Java : Mickael Baron - Robin56 -