Vous êtes sur la page 1sur 111

La FAQ JDBC

Date de publication : 11/08/2004

Dernière mise à jour : 17/05/2009

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums
java de www.developpez.com et de l'expérience personnelle des auteurs. Je tiens à
souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose
sont correctes. Les auteurs font le 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 les modalités de participation.

Bonne lecture à tous,

L'équipe Java
Ont contribué à cette FAQ :

L'équipe Java - Christophe Jollivet - Ioan Calapodescu - duj -


La FAQ JDBC

1. Introduction (4) .......................................................................................................................................................................... 4


2. Généralités (8) ........................................................................................................................................................................... 6
3. Les pilotes - Drivers (9) .......................................................................................................................................................... 11
4. La connexion (5) ..................................................................................................................................................................... 17
5. Sources de données - DataSources (7) ....................................................................................................................................20
6. Les instructions - Statement (24) ............................................................................................................................................ 24
6.1. Généralités (12) ...............................................................................................................................................................25
6.2. Les instructions paramétrées - PreparedStatement (5) ................................................................................................... 31
6.3. Les procédures stockées et fonctions - CallableStatement (7) .......................................................................................33
7. Les résultats - ResultSet (15) .................................................................................................................................................. 38
8. Les RowSet (24) ......................................................................................................................................................................49
8.1. Généralités (6) .................................................................................................................................................................50
8.2. Les RowSet déconnectés (CachedRowSet, etc.) (10) .................................................................................................... 54
8.3. Les WebRowSet (3) ....................................................................................................................................................... 61
8.4. Les FilteredRowSet (3) ...................................................................................................................................................65
8.5. Les JoinRowSet (2) ........................................................................................................................................................ 69
9. Les transactions (8) ................................................................................................................................................................. 71
10. Les types SQL et les types Java (11) ................................................................................................................................... 75
11. Les méta-données - MetaData (22) .......................................................................................................................................84
11.1. Généralités et informations sur le SGBD (11) .............................................................................................................85
11.2. Informations sur les tables (5) ......................................................................................................................................92
11.3. Informations sur les ResultSet (6) ................................................................................................................................96
12. La gestion des erreurs (4) ....................................................................................................................................................100
13. Mapping O/R, frameworks de persistance et autres API (13) ............................................................................................ 104
13.1. Généralités (3) .............................................................................................................................................................105
13.2. JDO (3) ....................................................................................................................................................................... 106
13.3. DbUtils (7) .................................................................................................................................................................. 107
14. Divers (4) ............................................................................................................................................................................. 109

-3-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Introduction


Comment bien utiliser cette FAQ ?
Auteurs : L'équipe Java ,
Le but :

Cette faq a été conçue pour être la plus simple possible d'utilisation. Elle tente d'apporter des réponses simples et
complètes aux questions auxquelles sont confrontés tous les débutants (et les autres).

L'organisation :

Les questions sont organisées par thème, les thèmes pouvant eux-même contenir des sous-thèmes. Lorsqu'une question
porte sur plusieurs thèmes, celle-ci est insérée dans chacun des thèmes rendant la recherche plus facile.

Les réponses :

Les réponses contiennent des explications et des codes sources. Certaines sont complétées de fichier à télécharger
contenant un programme de démonstration. Ces programmes sont volontairement très simples afin qu'il soit aisé de
localiser le code intéressant. Les réponses peuvent également être complétées de liens vers d'autres réponses, vers la
documentation en ligne de Sun ou vers un autre site en rapport.

Nouveautés et mises à jour :

Lors de l'ajout ou de la modification d'une question/réponse, un indicateur est placé à coté du titre de la question.
Cet indicateur reste visible pour une durée de 15 jours afin de vous permettre de voir rapidement les modifications
apportées.

J'espère que cette faq pourra répondre à vos questions. N'hésitez pas à nous faire part de tous commentaires/remarques/
critiques.

lien : Comment participer à cette FAQ?

Comment participer à cette FAQ?


Auteurs : L'équipe Java ,
Cette faq est ouverte à toute collaboration. Pour éviter la multiplication des versions, il serait préférable que toutes
collaborations soient transmises aux administrateurs de la faq.

Plusieurs compétences sont actuellement recherchées pour améliorer cette faq :

Rédacteur :

Bien évidemment, toute nouvelle question/réponse est la bienvenue.

Web designer :

Toute personne capable de faire une meilleure mise en page, une feuille de style ou de belles images...

Correcteur :

-4-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Malgré nos efforts, des fautes d'orthographe ou de grammaire peuvent subsister. Merci de contacter les administrateurs
si vous en débusquez une... Idem pour les liens erronés.

Pour savoir qui contacter, regardez à cette adresse : Contacts et participations

lien : Contacts et participations


lien : Rejoignez la rédaction de www.developpez.com
lien : Quels sont les droits de reproduction de cette faq ?

Quels sont les droits de reproduction de cette faq ?


Auteurs : L'équipe Java ,
Les sources présentés sur cette pages sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre,
la page de présentation constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004
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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est
déposée à la SACD.

lien : Comment participer à cette FAQ?

Remerciements
Auteurs : L'équipe Java ,
Un grand merci à tous ceux qui ont pris de leur temps pour la réalisation de cette FAQ.

Aux rédacteurs :

Remerciements tout d'abord à tous ceux qui ont rédigé les questions et les réponses.

Aux correcteurs :

Remerciements également aux personnes qui ont relu les textes pour supprimer un maximum de fautes de français.
Notamment merci à Anomaly

A l'équipe Java :

Remerciements tous particuliers aux membres de la rubrique Java pour leurs conseils, corrections, relectures, idées,
etc. Bref, merci pour leur travail d'équipe qui a permis de faire aboutir ce projet.

Aux visiteurs et membres de DVP :

Remerciements enfin à tous ceux qui ont consulté cette FAQ, et qui, par leurs remarques, nous ont aidé à la
perfectionner.

-5-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Généralités


Qu'est-ce que JDBC ?
Auteurs : Ioan Calapodescu ,
JDBC est une API (Application Programming Interface) java disponible depuis la version 1.1 du JDK. Pour note,
JDBC est un nom déposé et non un acronyme, même si en général on lui donne la définition suivante : Java DataBase
Connectivity.

Cette API est constituée d'un ensemble d'interfaces et de classes qui permettent l'accès, à partir de programmes java, à
des données tabulaires (i.e. triées sous forme de table ou de tableur). Par données tabulaires, on entends généralement
des bases de données contenues dans des SGBD relationnels. Mais, JDBC n'est pas restreinte à ce type de source de
données. On peux aussi accéder à des sources de données sous forme de fichiers (fichiers XML par exemple).

lien : Ou trouver plus d'informations sur JDBC ?

Quelques définitions utiles avant de commencer : SQL, ODBC, SGBDR


Auteurs : Ioan Calapodescu ,
Rappellons d'abord quelques notions élémentaires :

SQL (Structured Query Language) : Le "langage de requêtes structuré" est un langage d'interrogation universel
permettant la définition, la manipulation et le contrôle des données, pour les bases de données relationnelles. SQL est
un standard supporté par la plupart des SGBD.

SGBDR (Système de gestion de bases de données relationnelles) : Un SGBDR est un logiciel assurant la structuration,
le stockage, la maintenance, la mise à jour et la consultation d'une base de données relationnelle. Sachant qu'une base
de données relationnelle est une collection de données structurées sous forme de tableaux à deux dimensions (lignes et
colonnes). Exemples : Oracle, Sybase, MySql, DB2, Interbase, etc.

ODBC (Open DataBase Connectivity) : Interface écrite en C qui permet la communication avec les bases de données.
Tout comme JDBC, ODBC permet la manipulation des bases de données "indépendamment" du SGBD.

lien : Ou trouver plus d'informations sur SQL et les SGBDR ?

Que peut on faire avec JDBC ?


Auteurs : Ioan Calapodescu ,
L'API JDBC permet, entre autres :

• L'établissement d'une connexion avec le SGBD


• L'envoi de requêtes SQL au SGBD, à partir du programme java
• Le traitement, au niveau du programme, des données retournées par le SGBD
• Le traitement des méta-données de la connexion, de l'instruction ou des résultats

-6-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• Le traitement des erreurs retournées par le SGBD lors de l'exécution d'une instruction

lien : Architecture générale de JDBC.

A quels SGBDR puis-je me connecter avec JDBC ?


Auteurs : Ioan Calapodescu ,
L'API JDBC permet virtuellement de se connecter à n'importe quel SGBDR. On a donc indépendance de la plate-forme
(Java) et indépendance du SGBD (JDBC), c'est la philosophie même de Java : "Write Once, Run Anywhere".

L'utilisation du langage de programmation java en collaboration avec l'API JDBC est donc une solution véritablement
portable d'écrire des applications utilisant les bases de données.

Voici une liste non exhaustive des SGBD acessibles avec JDBC :

• DB2
• FoxPro
• Ingres
• Interbase
• MS Access
• MS SQL Server
• MySQL
• Oracle
• Paradox
• PostgreSQL
• Sybase

lien : Qu'est-ce qu'un driver ?


lien : Ou trouver des drivers ?

Architecture générale de JDBC.


Auteurs : Ioan Calapodescu ,
Voici l'architecture générale de JDBC :

-7-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

On peux distinguer sur ce schéma simplifié trois types de technologies. En jaune nous avons la technologie Java, dont
une partie de JDBC (gestionnaire et pilotes). Pour les trois premiers types de drivers, on remarque en vert la présence
d'intermédiaires non java comme les API natives ou les serveurs intermédiaires. Enfin, en bleu, viennent les différents
SGBD.

Remarque : les noms des drivers et SGBD sont donnés ici à titre d'exemple. Il en exite bien d'autres.

Et voici, les étapes généralement rencontrées dans un programme utilisant cette technologie :

• Chargement du driver correspondant au SGBD ciblé


• Ouverture d'une connexion vers la base de données
• Création d'une requête (Statement)
• Exécution de la requête

-8-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• Accès aux résultats de la requête


• Accès aux méta-données (des résultats, de la connexion, etc.)
• Gestions des erreurs (exceptions et warnings)
• Libération des ressources (fermeture de la connexion, etc.)

lien : Qu'est-ce qu'un driver ?


lien : Comment charger un driver ?
lien : A quels SGBDR puis-je me connecter avec JDBC ?
lien : Comment ouvrir une connexion à une base de données (DriverManager) ?

Quelles sont les différences entre JDBC 1.0, 2.0 et 3.0 ?


Auteurs : Ioan Calapodescu ,
L'API JDBC est présente depuis la version 1.1 de Java (JDBC 1.0). En conséquence elle a connu plusieurs versions.
Ces différentes versions on consisté en l'ajout de nouvelles fonctionnalités (classes et interfaces) ou en l'amélioration
des fonctionnalités déjà présentes. La dernière version en date, JDBC 3.0, est disponible depuis février 2002. Elle fait
partie intégrante de J2SE depuis la version 1.4.

• JDBC 1.0 : depuis le JDK 1.1. Formée du package java.sql


• JDBC 2.0 : depuis le JDK 1.2. Formée des packages java.sql et javax.sql
• JDBC 3.0 : depuis le JDK 1.4. Formée des packages java.sql, javax.sql et javax.sql.rowset

Pour de plus amples informations sur les différentes fonctionnalités apparues (dans tous les packages) au fil du temps
regardez la description du package java.sql.

Et JDBC 4.0 alors ? La version 4.0 de JDBC est déjà en cours de conception : JSR 221: JDBC 4.0 API Specification.
Elle prévoit notament l'intégration des nouveautés de la version 1.5 de J2SE, comme la généricité.

lien : Ou trouver plus d'informations sur JDBC ?

Ou trouver plus d'informations sur JDBC ?


Auteurs : Ioan Calapodescu ,
Sur le site de Sun :

• JDBC Technology
• JDBC API Documentation
• FAQ JDBC Sun
• JDBC Basic Tutorial
• JDBC Advanced Tutorial
• JDBC RowSet Tutorial

Sur www.developpez.com :

• Les meilleurs cours, tutoriels et documentations pour Java


• Tutoriels JDBC et SGBD avec Java

Sur jGuru :

• jGuru: JDBC 2.0 Fundamentals


• jGuru JDBC FAQ

-9-
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sur le site de votre SGBDR, par exemple :

• Oracle JDBC Frequently Asked Questions


• MySQL Connector/J Documentation

Si vous ne trouvez pas votre bonheur dans ces différentes sources, il reste le forum général java et le forum J2EE de
www.developpez.com

lien : Ou trouver plus d'informations sur SQL et les SGBDR ?

Ou trouver plus d'informations sur SQL et les SGBDR ?


Auteurs : Ioan Calapodescu ,
Pour plus d'informations sur le langage SQL et les SGBDR www.developpez.com vous propose ses cours, tutoriels,
faq's et forums dont :

• Généralités sur les SGBD


• Cours pour le langage SQL
• Forum général SGBD
• Forum langage SQL
• Forum Access
• Forum Oracle
• FAQ Access
• FAQ MySQL
• Livres SQL et SGBD

lien : Ou trouver plus d'informations sur JDBC ?

- 10 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les pilotes - Drivers


Qu'est-ce qu'un driver ?
Auteurs : Ioan Calapodescu ,
Un pilote ou driver JDBC est un "logiciel" qui permet d'établir une connexion entre un programme java et un système
de gestion de bases de données. Ce "logiciel" est en fait une implémentation de l'interface Driver, du package java.sql.
Le pont JDBC-ODBC est un exemple de driver JDBC, ce dernier permet l'interfaçage avec ODBC (il est contenu dans
J2SE : sun.jdbc.odbc.JdbcOdbcDriver).

Il existe 4 types de drivers JDBC (cf. Quels sont les différents types de driver JDBC ?) qui se différencient par leur
implémentation (notamment par l'utilisation ou non de méthodes natives)

Les drivers sont pris en charge par la classe DriverManager.

lien : Architecture générale de JDBC.


lien : Quels sont les différents types de driver JDBC ?
lien : Comment charger un driver ?
lien : java.sql.Driver
lien : java.sql.DriverManager

Quels sont les différents types de driver JDBC ?


Auteurs : Ioan Calapodescu ,
Les drivers JDBC sont disponibles sous forme de classes java (implémentant java.sql.Driver) contenues dans des fichiers
JAR (Java ARchive). L'installation est donc triviale, il suffit que le jar soit présent sur le disque dur et disponible dans
le CLASSPATH durant la compilation/exécution.

Il existe 4 types de drivers JDBC :

Le pont JDBC-ODBC (JDBC-ODBC bridge plus ODBC driver) :

Ce driver est présent dans J2SE (sun.jdbc.odbc.JdbcOdbcDriver). Il permet l'acces au SGBD via le driver ODBC.

Native-API partly-Java driver :

Ce type de driver traduit les appels de JDBC à un SGBD particulier, grâce à un mélange d'API java et d'API natives.

JDBC-Net pure Java driver :

Ce type de driver (écrit entièrement en java) passe par un serveur intermédiaire pour l'accès au SGBD.

Native-protocol pure Java driver :

Ce type de driver (écrit entièrement en java) se connecte directement au SGBD.

lien : Qu'est-ce qu'un driver ?


lien : Comment charger un driver ?

- 11 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Quel(s) driver(s) utiliser ?

Quel(s) driver(s) utiliser ?


Auteurs : Ioan Calapodescu ,
Il est difficile de répondre de façon catégorique à cette question. En effet, les quatre types de drivers disposent de
leurs avantages, inconvénients et spécificités. Mais, un ordre de préférence peut être donné en étudiant les trois critères
suivants : portabilité, respect des spécifications et performances.

La portabilité : Ce critère à toujours une place prépondérante dans les considérations sur le développement
d'applications Java. Sur ce point, les drivers de type 3 et 4, dits "purs java", mènent sur leurs homologues de type 1
et 2, qui utilisent des API natives. On peut, par exemple, noter l'impossibilité d'utiliser un driver de type 1 ou 2 dans
une Applet.

Le respect des spécifications : Ce critère est peut-être tout aussi important que le premier lors du choix d'un driver. En
effet, il est toujours préférable d'avoir un driver respectant (et implémentant) les dernières spécifications. Les facilités
de développement s'en voient naturellement accrues. Sur ce point, il est difficile de départager les drivers en fonction
de leur type, car tout dépend de l'implémentation. On peut simplement remarquer que le pont JDBC-ODBC (driver
de type 1 implémenté par Sun), un des plus populaires de son type, ne respecte que partiellement les spécifications de
JDBC 3.0. De plus, la popularité (*) des drivers de type 3 et 4 laisse présager d'un développement plus suivi.

Les performances : Sur ce dernier point l'utilisation d'API natives donne en général l'avantage aux drivers de type
1 ou 2. Ceci est à pondérer par le fait que cela deviens de moins en moins vrai. On peux prendre l'exemple d'Oracle
qui annonce que dans "la plupart des cas" le driver Thin est aussi (voir plus) rapide que son homologue de type 2, le
driver OCI.

En conclusion, nous pouvons dire que les drivers de type 3 ou 4 sont préférables à ceux de type 1 ou 2. Naturellement,
ceci est une analyse rapide et la conclusion n'est pas à prendre au pied de la lettre. Prenez le temps de vous documenter
et adaptez ces remarques en fonction de vos besoins.

* : environ 75 % des drivers disponibles. Observations faites sur les 210 drivers référencés sur le site de Sun en juillet 2004.

lien : Qu'est-ce qu'un driver ?


lien : Quels sont les différents types de driver JDBC ?

Ou trouver des drivers ?


Auteurs : Ioan Calapodescu ,
La principale source pour trouver un driver se trouve sur le site de Sun : JDBC technology-enabled drivers

Vous pourrez affiner votre recherche en fonction de plusieurs critères :

• Version de l'API JDBC


• Nom du distributeur
• Certification J2EE
• Type du driver
• SGBD
• Fonctionnalités avancées (DataSource, RowSet, etc.)

- 12 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Pour trouver des informations sur un driver spécifique la meilleure solution est de s'informer sur le site même du
distributeur.

lien : Qu'est-ce qu'un driver ?


lien : Quels sont les différents types de driver JDBC ?

Comment charger un driver ?


Auteurs : Ioan Calapodescu ,
Première méthode :

Utiliser la méthode Class.forName, qui aura pour effet d'enregistrer le Driver auprès du DriverManager. N'oubliez pas
de vérifier que le jar contenant le driver est bien dans le classpath ;-)

String nomDriver = "nom_du_driver";


try{
Class.forName(nomDriver);
}catch(ClassNotFoundException cnfe){
System.out.println("La classe "+nomDriver+" n'a pas été trouvée");
cnfe.printStackTrace();
}

En pratique, à cause d'implémentations imparfaites des spécifications, il sera parfois nécessaire d'utiliser cette syntaxe :

Class.forName(nomDriver).newInstance();

Voici quelques exemple :

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
//pour le pont JDBC-ODBC
Class.forName("com.mysql.jdbc.Driver");
//pour MySQL et ConnectorJ

Deuxième méthode :

Enregistrer directement une instance du driver auprès du DriverManager. Par exemple :

Driver monDriver = new com.mysql.jdbc.Driver();


DriverManager.registerDriver(monDriver);

Troisième méthode :

Enregistrer le driver comme un argument de la commande java, lors de l'exécution. Cela revient en fait à définir la
variable d'environnement jdbc.drivers.

java -cp .;mesDrivers.jar -Djdbc.drivers=une.implementation.de.Driver MonMain

lien : java.sql.Driver

- 13 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : java.sql.DriverManager

Comment connaître les drivers disponibles à partir d'une application ?


Auteurs : Ioan Calapodescu ,
Pour obtenir cette information, on peut utiliser la classe DriverManager :

for (Enumeration e = DriverManager.getDrivers(); e.hasMoreElements();){


Driver driver = (Driver)e.nextElement();
int majorVersion = driver.getMajorVersion();
int minorVersion = driver.getMinorVersion();
System.out.println("Driver = "+driver.getClass()+
" v"+majorVersion+"."+minorVersion);
}

lien : Comment obtenir des informations sur un Driver donné, à partir de l'application ?
lien : java.sql.Driver
lien : java.sql.DriverManager

Comment obtenir des informations sur un Driver donné, à partir de l'application ?


Auteurs : Ioan Calapodescu ,
Il faut utiliser les méthodes fournies par l'interface Driver :

Driver driver = ...;


String url = "url JDBC";
int majorVersion = driver.getMajorVersion();
int minorVersion = driver.getMinorVersion();
DriverPropertyInfo[] props = driver.getPropertyInfo(url,null);
System.out.println("Driver class = "+driver.getClass()+
" v"+majorVersion+"."+minorVersion);
for(int i=0 ;i<props.length;i++){
DriverPropertyInfo prop = props[i];
System.out.println("Prop name = "+prop.name);
System.out.println("Prop description = "+prop.description);
System.out.println("Prop value = "+prop.value);
if(prop.choices!=null){
for(int j=0;j<prop.choices.length;j++){
System.out.println("prop choice "+j+" = "+prop.choices[j]);
}
}
}

Voici, la sortie pour MySQL Connector/J :

Driver class com.mysql.jdbc.Driver v3.0


Prop name = HOST
Prop description = Hostname of MySQL Server
Prop value = localhost
Prop name = PORT
Prop description = Port number of MySQL Server
Prop value = 3306
Prop name = DBNAME
Prop description = Database name
Prop value = test
Prop name = user
Prop description = Username to authenticate as

- 14 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Prop value = null


Prop name = password
Prop description = Password to use for authentication
Prop value = null
Prop name = autoReconnect
Prop description = Should the driver try to re-establish bad connections?
Prop value = false
prop choice 0 = true
prop choice 1 = false
Prop name = maxReconnects
Prop description = Maximum number of reconnects to attempt if autoReconnect is true
Prop value = 3
Prop name = initialTimeout
Prop description = Initial timeout (seconds) to wait between failed connections
Prop value = 2
//+ 90 lignes

lien : Comment connaître les drivers disponibles à partir d'une application ?


lien : java.sql.Driver
lien : java.sql.DriverManager

Comment rediriger les logs du DriverManager ?


Auteurs : Ioan Calapodescu ,
Cette fonctionnalité peux être utile durant le debuggage, pour lister les interactions entre le DriverManager et tous les
Driver chargés. Il faut utiliser la méthode setLogWriter(PrintWriter out) de la classe DriverManager. Voici un exemple
redirigeant ces informations sur la sortie standard :

DriverManager.setLogWriter(new PrintWriter(System.out));
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection = DriverManager.getConnection(url,user,password);

Le résultat ressemblera à ceci :

DriverManager.initialize: jdbc.drivers = null


JDBC DriverManager initialized
registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@3fa5ac]
DriverManager.getConnection("jdbc:mysql://localhost/test")
trying driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@3fa5ac]
getConnection returning driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@3fa5ac]

Attention : cette méthode obéit à des règles de sécurité cf. doc de DriverManager

lien : Qu'est-ce qu'un driver ?


lien : Comment ouvrir une connexion à une base de données (DriverManager) ?
lien : java.sql.Driver
lien : java.sql.DriverManager

Comment définir le temps d'attente pour une connexion ?


Auteurs : Ioan Calapodescu ,
Pour définir le temps d'attente maximum pour établir la connexion au SGBDR, il faut utiliser une des méthodes statiques
de la classe DriverManager.

- 15 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

int temps = 5; // en secondes


DriverManager.setLoginTimeout(temps);

lien : java.sql.Driver
lien : java.sql.DriverManager

- 16 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > La connexion


Comment ouvrir une connexion à une base de données (DriverManager) ?
Auteurs : Ioan Calapodescu ,
Une connexion à une base de données avec JDBC est représentée par une instance de la classe java.sql.Connection.
Pour ouvrir une connexion vers une base de données, il suffit de spécifier l'url de connexion, le login et le password, à
la méthode getConnection de DriverManager. Par exemple :

String url = "url";


String login = "log";
String password = "pass";
try{
Connection connection = DriverManager.getConnection(url,login,password);
//interaction avec la base
}
catch(SQLException sqle){
//cf Comment gérer les erreurs ?
}
finally{
//cf Comment bien fermer une connexion ?
}

Une seconde possibilité est de spécifier au DriverManager un ensemble de propriétés. Ces propriété sont définies en
fonction du Driver utilisé (cf. Comment obtenir des informations sur un Driver donné, à partir de l'application ? ).

String login = "log";


String password = "pass";
try{
Properties props = new Properties();
props.setProperty("user","userName");
props.setProperty("password","motDePasse");
props.setProperty("autoReconnect", "true");
Connection connection = DriverManager.getConnection(url,props);
//interaction avec la base
}
catch(SQLException sqle){
//cf Comment gérer les erreurs ?
}
finally{
//cf Comment bien fermer une connexion ?
}

Le mot de passe et le nom d'utilisateur font partie des propriétés standards.

lien : Comment sont formées les URL JDBC ?


lien : Qu'est-ce qu'un driver ?
lien : Comment obtenir des informations sur un Driver donné, à partir de l'application ?
lien : Comment fermer une connexion ?
lien : Comment gérer une SQLException ?
lien : java.sql.Connection
lien : java.sql.DriverManager

Comment sont formées les URL JDBC ?


Auteurs : Ioan Calapodescu ,
Les URL JDBC sont définies sous forme de String selon ce schéma :

- 17 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

String url = "jdbc:<subprotocol>:<subname>"

• <jdbc>: Le protocole dans une URL JDBC est toujours jdbc


• <subprotocol> Cela correspond au nom du driver ou au mécanisme de connexion à la base de données.
• <subname> Une manière d'identifier la source de données. Ce dernier élément dépend complètement du sous-
protocole et du driver.

Par exemple :

• jdbc:odbc:maBase;CacheSize=30;ExtensionCase=LOWER
• jdbc:mysql://localhost/maBase
• jdbc:oracle:oci8@:maBase
• jdbc:oracle:thin@://localhost:8000:maBase
• jdbc:sybase:Tds:localhost:5020/maBase

Il est nécessaire de se documenter auprès du fournisseur du driver.

lien : Comment ouvrir une connexion à une base de données (DriverManager) ?


lien : Ou trouver des drivers ?
lien : Ou trouver plus d'informations sur JDBC ?
lien : java.sql.Connection

Comment fermer une connexion ?


Auteurs : Ioan Calapodescu ,
La connexion est fermée automatiquement par le garbage collector, mais il est toujours préférable de fermer soi même
une connexion. De manière générale il est nécessaire de bien gérer les exceptions. Votre code devrait toujours ressembler
à ceci :

String driver = "nom.du.driver";


String url = "url";
String login = "login"
String password = "password";
Connection connection = null;
try{
Class.forName(driver);
connection = DriverManager.getConnection(url,login,password);
//travail avec les données
}
catch(ClassNotFoundException cnfe){
System.out.println("Driver introuvable : ");
cnfe.printStackTrace();
}
catch(SQLException sqle){
System.out.println("Erreur SQL : ");
//Cf. Comment gérer les erreurs ?
}
catch(Exception e){
System.out.println("Autre erreur : ");
e.printStackTrace();
}
finally
{
if(connection!=null){try{connection.close()}catch(Exception e){e.printStackTrace();}}
//etc.

- 18 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment gérer une SQLException ?


lien : java.sql.Connection

Comment savoir si une connexion est fermée ?


Auteurs : Ioan Calapodescu ,
Pour savoir si la connexion est fermée il faut utiliser la méthode isClosed() de Connection. Par exemple :

if(connection.isClosed()){
//on essaye de réinitialiser la connexion
connection = DriverManager.getConnection(...);
}else{
//traitement normal
}

Attention : cette méthode est sûre de renvoyer true seulement si la méthode close a été appelée. En définitive, elle ne peux
pas servir à determiner si une connexion est valide ou non. Pour cela, il faudra gérer une potentielle SQLException.

Comment savoir qu'une connexion est valide ?


Auteurs : Ioan Calapodescu ,
La méthode isClosed de Connection, n'est pas suffisante pour tester la validité d'une connexion. En effet celle-ci retourne
true si et seulement si la méthode close à été appelée. La seule possibilité reste de faire une sorte de "ping" vers le
serveur. Ce "ping" consiste en l'exécution d'une requête simple. Par exemple :

public static boolean isValid(Connection connection){


if(connection==null){
return false;
}
ResultSet ping = null;
try{
if(connection.isClosed()){return false;}
ping = connection.createStatement().executeQuery("SELECT 1");
return ping.next();
}catch(SQLException sqle){
return false;
}
finally{
if(ping!=null){try{ping.close();}catch(Exception e){}}
}
}

lien : Comment savoir si une connexion est fermée ?

- 19 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Sources de données - DataSources


Qu'est ce qu'une DataSource ?
Auteurs : Ioan Calapodescu ,
Une DataSource (package javax.sql) est une interface représentant une "source de données". Cette "source de données"
est en fait une simple fabrique de connexions vers la source de données physique. Ce mécanisme, apparu avec JDBC
3.0, est désormais préféré au DriverManager. Pour connaître les raisons de cette préférence et les atouts de DataSource,
regardez : Pourquoi utiliser une DataSource ? .

En général, une DataSource est utilisée (appelée) via JNDI (Java Naming and Directory Interface). Mais, ce n'est pas
une obligation, c'est simplement ce qui est le plus courament rencontré.

Il existe trois grands types d'implémentations pour une DataSource :

• Basiques : ces implémentations produisent des instances de Connection normales, telles que l'on pourrait les
obtenir avec DriverManager.
• Pool de connexions : ces implémentations produisent des instances de Connection qui appartiennent à un pool.
Pour savoir à quoi celà correspond exactement, regardez : Qu'est ce qu'un pool de connexions ? .
• Transactions distribuées : ces implémentations produisent des instances de Connection, qui peuvent être
utilisées pour des transactions ditribuées. En général, ce type de DataSource utilise aussi les pools de
connexions.

Pour savoir ou trouver des implémentations de dataSource, regardez : Ou trouver des implémentations de DataSource ?
.

lien : Pourquoi utiliser une DataSource ?


lien : Qu'est ce qu'un pool de connexions ?
lien : Ou trouver des implémentations de DataSource ?

Pourquoi utiliser une DataSource ?


Auteurs : Ioan Calapodescu ,
L'accès à une base de données via une DataSource est un mécanisme désormais préféré au DriverManager. Voici
quelques raisons à cette "préférence" :

• Les drivers ne sont plus obligés de s'enregistrer eux même, comme ils le faisaient avec DriverManager.
• Les implémentations de DataSource permettent de facilement changer les propriétés des sources de données.
Par exemple, il n'est plus nécessaire de modifier du code applicatif lors de changements concernant la base de
données, son emplacement physique ou encore un driver.
• Les instances de Connection fournies par les DataSouce ont des capacités étendues (pool de connexion,
transactions ditribuées, etc.).

Il y a d'autres avantages à utiliser les DataSource. Pour des informations plus détaillées, vous pouvez suivre ce liens :


Gestion d'un pool de connexions (avec Tomcat), par Christophe Jollivet

Cours JDBC de la rubrique Java

Description détaillé de javax.sql

- 20 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC


Resource Connections (J2EE 1.4 Tutorial)

Qu'est ce qu'un pool de connexions ?


Auteurs : Ioan Calapodescu ,
Un pool de connexions est un mécanisme permettant de réutiliser les connexions créées. En effet, la création systématique
de nouvelles instances de Connection peut parfois devenir très lourd en consommation de ressources. Pour éviter celà,
un pool de connexions ne ferme pas les connexions lors de l'appel à la méthode close(). Au lieu de fermer directement
la connexion, celle-ci est "retournée" au pool et peut être utilisée ultérieurement.

La gestion du pool se fait en général de manière transparente pour l'utilisateur.

//récupération d'une DataSource, via JNDI d'habitude


DataSource source = ...;
//récupération d'une connexion du pool
Connection connection = source.getConnection("user", "password");
//utilisation de la Connection

// ...

//on "retourne" la connexion au pool, en la "fermant"


connection.close();

Voici les quelques classes concernant les pools de connexions du package javax.sql :

• ConnectionPoolDataSource : cette interface représente une source de données gérant les pools de connexions.
• PooledConnection : cette interface représente une connexions appartenant à un pool.
• ConnectionEventListener : ce listener permet de se mettre à l'écoute des événements relatifs à une
PooledConnection. La méthode connectionClosed(ConnectionEvent event) est appellée lorsqu'une connexion est
retournée au pool. La méthode connectionErrorOccurred(ConnectionEvent event) est appellée lors d'une erreur
lors de la connexion (crash du serveur, par exemple). Le listener est "prioritaire" par rapport à l'application
(i.e. les méthodes sont appellées avant que le driver informe l'application d'une SQLException).
• ConnectionEvent : cette classe représente un événement de ConnectionEventListener. Deux informations sont
accessibles à partir de cet événement : la PooledConnection (source) et la SQLException, si elle existe.

Attention, aucune méthode de javax.sql ne retourne directement une ConnectionPoolDataSource. Pour pouvoir utiliser
les méthodes spécifiques de cette interface vous devrez faire vous même le "casting" adéquat.

Suivez les liens ci-dessous pour des exemples pratiques de création et d'utilisation d'un pool de connexions.

lien : Comment configurer une DataSource avec Tomcat ?


lien : Ou trouver des implémentations de DataSource ?

Ou trouver des implémentations de DataSource ?


Auteurs : Ioan Calapodescu ,
De nombreuses implémentations de DataSource existent. Celles-ci sont fournies par les fournisseurs de Driver ou de
manière indépendante (comme DBCP par exemple). Voici quelques exemple et liens :

- 21 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• DBCP (Database Connection Pool) : Cette API du projet Jakarta Commons permet d'obtenir des
implémentations de DataSource avec pool de connexions. Elle est intégrée et utilisée par de nombreux projets
(Tomcat par exemple).
• JDBC-ODBC Bridge : Le pont JDBC-ODBC proposé par Sun propose aussi des implémentations de
DataSource. Pour plus d'informations suivez ce lien : http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/bridge.html
• Il existe de nombreux projets Open-Source comme proxool ou encore c3p0.
• De très nombreux distributeurs de drivers fournissent leurs propres implémentations (MySQL, Oracle,
Sybase, etc.). Pour une liste détaillée, regardez JDBC technology-enabled drivers (sélectionnez simplement
Conn.Pooling et/ou DataSource pour les fonctionnalités requises).

Comment configurer une DataSource (exemple DBCP) ?


Auteurs : Ioan Calapodescu ,
Voici un exemple de configuration d'une DataSource avec l'api DBCP. Pour cet exemple, on va utiliser JNDI, mais vous
pouvez très bien utiliser directement l'implémentation (BasicDataSource).

Lien d'une DataSource à un contexte JNDI


//initialisation du contexte
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
InitialContext ic = new InitialContext();

// création d'une référence sur la DataSource


Reference ref = new Reference("javax.sql.DataSource",
"org.apache.commons.dbcp.BasicDataSourceFactory",
null);
ref.add(new StringRefAddr("driverClassName", "com.mysql.jdbc.Driver"));
ref.add(new StringRefAddr("url", "jdbc:mysql://localhost/mabase"));
ref.add(new StringRefAddr("username", "xxx"));
ref.add(new StringRefAddr("password", "xxx"));

//liaison de la DataSource au contexte


ic.rebind("jdbc/MaDataSource", ref);

Une fois ce lien créé, il ne vous reste plus qu'à récupérer la DataSource comme ceci :

//récupération de la DataSource à partir du contexte


Context ctx = new InitialContext();
DataSource source = (DataSource)ctx.lookup("jdbc/MaDataSource");

//récupération d'une Connection


Connection connection = source.getConnection();
//...

Vous pouvez trouver d'autres exemples d'utilisation de DBCP à ces adresses :

• DBCP : JNDI Howto


• DBCP examples

lien : Comment configurer une DataSource avec Struts ?

- 22 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment configurer une DataSource avec Tomcat ?

Comment configurer une DataSource avec Tomcat ?


Auteurs : Ioan Calapodescu ,
Pour savoir comment configurer un pool de connexions avec Tomcat, vous pouvez lire le tutoriel de Christophe Jollivet :
Gestion d'un pool de connexions SGBD par Tomcat.

D'autres exemples sont disponibles pour DBCP et Tomcat dans la documentation de celui-ci : JNDI Datasource HOW-
TO.

Comment configurer une DataSource avec Struts ?


Auteurs : Ioan Calapodescu ,
Vous pouvez trouver des exemples de configuration de DataSource avec Struts dans la FAQ Struts :

• Comment utiliser une DataSource avec Struts ?


• Comment utiliser plusieurs DataSources avec Struts ?

- 23 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les instructions - Statement

- 24 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les instructions - Statement > Généralités


Comment créer un Statement ?
Auteurs : Ioan Calapodescu ,
L'interface Statement représente une instruction SQL. L'obtention d'une instance de cette interface se fait à partir de
la Connection :

try{
Connection connection = ...
Statement statement = connection.createStatement();
}
catch(Exception e){
//cf. Comment gérer les erreurs ?
}

Une deuxième méthode permet de spécifier le type des ResultSet crées avec ce Statement. Voir Quels sont les différents
types de ResultSet ?. Par exemple :

Statement statement = connection.createStatement(


ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);

lien : Que renvoie l'exécution d'un Statement ?


lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?
lien : Quels sont les différents types de ResultSet ?

Comment exécuter un Statement ?


Auteurs : Ioan Calapodescu ,
L'interface Statement propose une dizaine de méthodes permettant l'exécution d'expressions SQL. On peux les
regrouper par catégories :

• Les méthodes execute : méthodes génériques pour n'importe quelle expression SQL.
• Les méthodes executeQuery : méthodes appropriées à l'exécution d'un SELECT.
• Les méthodes executeUpdate : méthodes appropriées à l'exécution d'une instruction menant à la modification
de la BD (INSERT, UPDATE, DELETE, CREATE, etc.).
• Les méthodes executeBatch : Voir la partie réservée aux transactions

Voici quelques exemples :

Statement statement = connection.createStatement();


boolean result = statement.execute("SELECT * FROM MATABLE");
ResultSet resultSet = connection.executeQuery("SELECT ATTRIBUT1, ATTRIBUT2 FROM MATABLE");
int col = statement.executeUpdate("INSERT INTO MATABLE VALUES(15,'bonjour',7.0)");

lien : Que renvoie l'exécution d'un Statement ?

- 25 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?

Que renvoie l'exécution d'un Statement ?


Auteurs : Ioan Calapodescu ,
Le retour d'une méthode execute XXX dépend du type de celle-ci :

• execute : un boolean valant true si l'instruction renvoie un ResultSet, false sinon


• executeQuery : un ResultSet contenant les résultats (ne retourne jamais null)
• executeUpdate : un int indiquant le nombre de tuples (lignes) modifiés pour un INSERT, UPDATE et DELETE,
ou alors 0 pour les instructions ne retournant rien (CREATE par exemple)
• executeBatch : int[] : un tableau d'entiers indiquant le nombre de tuples modifiés pour chaque commande
contenue dans le batch. Ce tableau est ordonné selon l'ordre des ajouts au batch.

lien : Comment récupérer un ResultSet lors de l'utilisation de la méthode execute ?


lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?

Peut-on créer une requête spécifique à un SGBDR ?


Auteurs : Ioan Calapodescu ,
En règle générale la réponse est oui. En pratique cela dépendra de l'implémentation du Driver. Cela implique plusieurs
choses :

• Possibilité d'utiliser des types spécifiques au SGBD


• Possibilité d'utiliser des mots réservés au SGBD : Comment obtenir la liste des mots clefs SQL non standard
d'un SGBDR ?
• Possibilité d'utiliser les extensions procédurales : par exemple PL/SQL pour oracle, T/SQL pour Sybase, etc ...
• Possibilité d'appeler des fonctions spécifiques : procédures stockées par exemple. Dans ce dernier cas il est tout
de même conseillé d'utiliser la syntaxe d'échappement.

lien : Qu'est-ce que la syntaxe d'échappement ?


lien : Qu'est-ce qu'un CallableStatement ?
lien : Comment obtenir la liste des mots clefs SQL non standard d'un SGBDR ?
lien : Comment connaître les types SQL supportés par la base de données ?

Je n'ai pas d'exception, mais la méthode executeXXX ne fais pas ce que je veux ?
Auteurs : Ioan Calapodescu ,
Dans ce cas de figure, vérifiez :

• que vous n'avez pas de warning :


• que votre requête SQL est correcte, en la lançant directement avec le SGBD

- 26 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• que vous utilisez la bonne méthode execute : par exemple, un execute ou un executeUpdate pour "INSERT
INTO ..."

lien : Que sont les SQLWarning ?

Comment gérer le timeout de l'exécution d'une instruction ?


Auteurs : Ioan Calapodescu ,
L'interface Statement fourni pour cela les méthodes setQueryTimeout(int) et getQueryTimeout(). Par exemple :

Statement statement = ...


System.out.println("timeout par défaut = "+statement.getQueryTimeout());
statement.setQueryTimeout(2);
//le temps exprimé en secondes

Si le temps accordé à la requête est dépassé, une SQLException est levée.

lien : Comment définir le temps d'attente pour une connexion ?


lien : Comment gérer une SQLException ?

Comment récupérer un ResultSet lors de l'utilisation de la méthode execute ?


Auteurs : Ioan Calapodescu ,
La méthode execute renvoie un boolean indiquant la présence ou non d'un ResultSet. Pour le récupérer, il suffit de
faire comme ceci :

String url = "url";


String login = "log";
String password = "pass";
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try{
connection = DriverManager.getConnection(url,login,password);
statement = connection.createStatement();
boolean rs = statement.execute("SELECT * FROM MaTable");
if(rs){
resultSet = statement.getResultSet();
}else{
System.out.println("Il n'y a pas de ResultSet, peut-être une mise à jour : ");
int nbTuples = statement.getUpdateCount();
System.out.println("Nombre de tuples mis à jour = "+nbTuples);
}
}
catch(SQLException sqle){
//cf Comment gérer les erreurs ?
}
finally{
//cf Comment bien fermer une connexion ?
//cf Doit-on fermer un Statement ?
//cf Doit-on fermer un ResultSet ?

- 27 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?

Comment limiter le nombre de lignes des ResultSet renvoyées par l'instruction ?


Auteurs : Ioan Calapodescu ,
Il faut utiliser la méthode setMaxRows(int max) de Statement. Par exemple :

Statement statement = ...;


System.out.println("max rows : "+statement.getMaxRows());
statement.setMaxRows(200);

Les lignes dépassant ce maximum ne sont tout simplement pas retournées.

Une valeur de 0 signifie qu'il n'y a pas de maximum.

Une SQLException est levée si il y a une erreur durant une exécution ou si max est négatif.

lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?

Comment récupérer plusieurs ResultSet depuis le Statement ?


Auteurs : Ioan Calapodescu ,
La méthode getMoreResults() permet de vérifier la présence d'autres ResultSet. Par exemple :

Statement statement = ...;


if (!statement.execute()) {
System.out.println("La requête ne renvoie pas de ResultSet");
} else {
ResultSet premierResultSet = statement.getResultSet();
if (statement.getMoreResults(Statement.KEEP_CURRENT_RESULT)) {
ResultSet secondResultSet = statement.getResultSet();

// maintenant les deux ResultSet sont ouverts et prêts à être utilisés


premierResultSet.next();
secondResultSet.next();
// ...
}else{
System.out.println("Il n'y a pas de second ResultSet");
}
}

Les arguments de la méthode getMoreResults peuvent prendre les valeurs suivantes :

• Statement.CLOSE_CURRENT_RESULT : Le ResultSet courant doit être fermé lors de l'appel à la méthode


getMoreResults.
• Statement.CLOSE_ALL_RESULTS : Tous les ResultSet précédemment ouverts doivent être fermés lors de
l'appel à la méthode getMoreResults.
• Statement.KEEP_CURRENT_RESULT : Le ResultSet courant ne doit pas être fermé lors de l'appel à la
méthode getMoreResults.

- 28 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

L'argument par défaut est Statement.CLOSE_ALL_RESULTS.


lien : Comment passer les paramètres à la procédure (IN parameter) ?

Comment récupérer les clefs auto-générées par l'exécution du Statement ?


Auteurs : Ioan Calapodescu ,
Pour récupérer les clefs auto-générées par l'exécution d'une requête, il faut utiliser la méthode
execute(String sql, int autoGeneratedKeys)(ou executeUpdate). L'entier autoGeneratedKeys doit prendre la valeur
Statement.RETURN_GENERATED_KEYS.

Statement statement = ...


String commandeSQL = " ...";
statement.executeUpdate(commandeSQL,Statement.RETURN_GENERATED_KEYS);
//Les clefs auto-générées sont retournées sous forme de ResultSet
ResultSet clefs = statement.getGeneratedKeys();
if(clefs.next()){
System.out.printn("La première clef auto-générée vaut ");
System.out.printn(clefs.getObject(1));
}

On peux aussi limiter les clefs conservées en utilisant executeXXX(String sql, int[] columnIndexes) ou
executeXXX(String sql, String[] columnNames) .Les arguments représentent les indexes/noms des colonnes à observer
(NB : les indexes commencent à 1). Une SQLException est levée si les indexes/noms des colonnes sont éronnés ou si
l'instruction SQL n'est pas de type INSERT, UPDATE ou DELETE.

lien : Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?
lien : Comment retrouver les valeurs contenues dans un ResultSet ?
lien : Comment parcourir un ResultSet ?

Qu'est-ce que la syntaxe d'échappement ?


Auteurs : Ioan Calapodescu ,
La syntaxe d'échappement est définie par un bloc de code à l'intérieur de l'instruction SQL. Ce morceau de code est
contenu entre des guillemets. Cette syntaxe permet d'indiquer au Driver que le code n'est pas du SQL et doit être traité
de manière spécifique.

String sql = "{motClefs ... parametres}"

Cette syntaxe peux être utilisée pour :

La gestion des caractères spéciaux, dans LIKE, de manière indépendante du SGBD :

String sql = "SELECT * FROM Annuaire WHERE nom LIKE '%{escape '''}%'";
//sélection dans un annuaire des personnes ayant une apostrophe dans leur nom
ResultSet resultat = statement.executeQuery(sql);

L'appel de fonctions spécifiques ou non au SGBD :

String sql = "SELECT {fn curdate()}, {fn user()}";


ResultSet resultat = statement.executeQuery(sql);
resultSet.next();

- 29 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

System.out.println("On est le : "+result.getObject(1));


System.out.println("L'utilisateur est : "+result.getObject(2));

L'appel de procédures stockées :

String sql = "{call maProcedure(?, ?)}";


//appel d'une procédure à deux arguments

//Cf. le chapitre sur les procédures stockées


CallableStatement call = connection.prepareCall(sql);

Le formatage des données temporelles (date, time et timestamp) :

{d 'yyyy-mm-dd'}
//format pour DATE
{t 'hh:mm:ss'}
//format pour TIME
{ts 'yyyy-mm-dd hh:mm:ss.f . . .'}
//format pour TIMESTAMP

lien : Qu'est-ce qu'un CallableStatement ?


lien : Comment avoir la liste de toutes les procédures stockées dans une base de données ?
lien : Comment obtenir la liste des fonctions (numériques, système, etc.) ?
lien : Comment obtenir la liste des mots clefs SQL non standard d'un SGBDR ?

Doit on fermer un Statement ?


Auteurs : Ioan Calapodescu ,
Tout comme pour une Connection, même si le Garbage Collector, libérera les ressources allouées au Statement, il est
conseillé de le fermer explicitement.

Connection connection = null;


Statement statement = null;
try{
//initialisation de la connexion et du statement
}
catch(SQLException sqle){}
catch(AutreException ae){}
finally{
if(statement !=null){try{statement.close();}catch(Exception e){e.printStackTrace();}}
if(connection !=null){try{connection.close();}catch(Exception e){e.printStackTrace();}}
}

lien : Comment fermer une connexion ?


lien : Doit on fermer un ResultSet ?

- 30 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les instructions - Statement > Les instructions paramétrées - PreparedStatement
Qu'est-ce qu'un PreparedStatement ?
Auteurs : Ioan Calapodescu ,
L'interface PreparedStatement étend Statement et représente une instruction paramétrée. Cette interface diffère de
Statement sur deux points principaux :

• Les instances de PreparedStatement contiennent une instruction SQL dèjà compilée. D'où le terme prepared.
Cela améliore notamment les performances si cette instruction doit être appelée de nombreuses fois.
• Les instructions SQL des instances de PreparedStatement contiennent un ou plusieurs paramètres d'entrée, non
spécifiés lors de la création de l'instruction. Ces paramètres sont représentés par des points d'interrogation(?).
Ces paramètres doivent être spécifiés avant l'exécution.

L'exécution des PreparedStatement est identique à celle des simples Statement, à la différence près qu'il n'y a pas
d'argument aux méthodes executeXXX.

Comment créer un PreparedStatement ?


Auteurs : Ioan Calapodescu ,
L'instantiation de PreparedStatement se fait à partir de la classe Connection, grâce aux méthodes prepareStatement.
Voici quelques exemples :

Connection connection = ...;


PreparedStatement prep1 = connection.prepareStatement("SELECT * FROM Annuaire WHERE nom = ?");
//requête paramétrée pour rechercher un nom dans un Annuaire
PreparedStatement prep2 =
connection.prepareStatement("UPDATE Annuaire SET noTel = ? WHERE nom = ?");
//requête paramétrée pouvant servir à mettre à jour le numéro de tél. d'un abonné donné
PreparedStatement prep3 = connection.prepareStatement("SELECT Attribut1, Attribut2 FROM MaTable");
// il peut ne pas y avoir de paramètres : sélection de deux attributs de la table MaTable

//etc.

Une fois l'instance de PreparedStatement récupérée, il ne reste plus qu'à définir la valeur des paramètres et à l'exécuter.

Comment passer/vider les paramètres du PreparedStatement(IN parameters) ?


Auteurs : Ioan Calapodescu ,
Le passage des paramètres d'entrée des PreparedStatement se fait grâce à l'ensemble des méthodes setXXX. Il est
important de connaître les correspondances entre les types SQL et les types java (cf. Tableau de relations).

String sql = "UPDATE Stocks SET prix = ?, quantite = ? WHERE nom = ?";
//préparation de la requête
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//on assigne un décimal au premier paramètre
preparedStatement.setBigDecimal(1,15.6);
//on assigne un entier au second paramètre
preparedStatement.setIntl(2,256);
//on assigne une chaîne de caractères au troisième
preparedStatement.setStringl(3,"café");
//exécution de la requête

- 31 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

preparedStatement.executeUpdate();

Pour vider un paramètre on peut utiliser la méthode setXXX correspondante, cela a pour effet d'écraser la valeur passée
précédemment. Pour vider tous les paramètres, vous pouvez utiliser la méthode clearParameters().

lien : Tableau de relations


lien : Comment passer un paramètre NULL (type SQL) ?

Comment passer des paramètres avec la méthode setObject ?


Auteurs : Ioan Calapodescu ,
La méthode setObject permet de passer n'importe quel type d'argument. Cette méthode, en plus de l'index du paramètre
et de la valeur de celui-ci, peut prendre en argument un entier définissant le type SQL.

L'objet java, passé comme valeur, sera convertit dans le type SQL indiqué avant d'être envoyé au SGBD. Si ce dernier
implémente SQLData, le driver appellera la méthode writeSQL pour l'écrire dans la base de données.

String sql = "INSERT INTO Annuaire (nom, prenom, tel) VALUES(?,?,?)";


PreparedStatement statement = connection.prepareStatement(sql);
//en spécifiant bien les types SQL cibles
statement.setObject(1,"toto", Types.VARCHAR);
statement.setObject(2,"titi",Types.VARCHAR);
statement.setObject(3,new Integer(123),Types.INTEGER);
statement.executeUpdate();
//on peut ne pas spécifier le type sql
statement.setObject(1,"bobo");
statement.setObject(2,"bibi");
statement.setObject(3,new Integer(456));
statement.executeUpdate();
//certains types seront automatiquement convertis, d'autres non
statement.setObject(1,"nono");
statement.setObject(2,"nini");
statement.setObject(3,"789",Types.INTEGER);
statement.executeUpdate();

Une dernière méthode setObject prend en argument un entier définissant le nombre de chiffres après la virgule pour
Types.NUMERIC et Types.DECIMAL. En cas de types incompatibles une SQLException sera levée lors de l'exécution.

lien : Tableau de relations

Comment passer un paramètre NULL (type SQL) ?


Auteurs : Ioan Calapodescu ,
Si la méthode setXXX prends en argument un Object java, on peut passer directement null. Sinon, pour les types
primitifs, on peut utiliser les méthodes setNull de PreparedStatement. Par exemple :

String sql = "INSERT INTO MaTable (unString, unInt, uneDate) VALUES (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setObject(1,null, Types.VARCHAR);
statement.setNull(2);
statement.setDate(3,null);

lien : Comment passer/vider les paramètres du PreparedStatement(IN parameters) ?


lien : Comment savoir si une valeur correspond au type SQL NULL ?

- 32 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les instructions - Statement > Les procédures stockées et fonctions - CallableStatement
Qu'est-ce qu'un CallableStatement ?
Auteurs : Ioan Calapodescu ,
L'interface CallableStatement, qui étends PreparedStatement, permet de faire appel aux procédures stockées et
aux fonctions de manière standard pour tous les SGBD. Pour que cet appel soit indépendant du SGBD ciblé,
CallableStatement utilise la syntaxe d'échappement (Cf. Qu'est-ce que la syntaxe d'échappement ?).

La principale différence avec les PreparedStatement se situe au niveau des paramètres. Ceux-ci sont toujours définis par
des points d'interrogation, mais en plus des paramètres d'entrée (IN), CallableStatement peux avoir des paramètres de
sortie (OUT). Ces paramètres définissent le résultats de la procédure. On peux aussi combiner ces deux types (INOUT).

lien : Comment créer un CallableStatement ?


lien : Qu'est-ce que la syntaxe d'échappement ?
lien : Comment avoir la liste de toutes les procédures stockées dans une base de données ?

Comment créer un CallableStatement ?


Auteurs : Ioan Calapodescu ,
Une instance de CallableStatement s'obtient grâce aux méthodes prepareCall de Connection. Le premier argument de
ces méthodes est une chaîne de caractères définissant l'instruction SQL. Cette chaîne de caractères utilise la syntaxe
d'échappement et peux avoir deux formes.

Pour les procédures stockées :

String sql = "{call nomDeLaProcedure[(?, ?, ...)]}";


//[(?, ?, ...)] sont les éventuels arguments de la procédure

//ces arguments peuvent être de type IN, OUT ou INOUT


CallableStatement statement = connection.prepareCall(sql);

Pour les fonctions (procédures stockées renvoyant un résultat) :

String sql = "{? = call nomDeLaProcedure[(?, ?, ...)]}";


//le premier ? est le résultat de la procédure

//[(?, ?, ...)] sont les éventuels arguments de la procédure


CallableStatement statement = connection.prepareCall(sql);

Les autres arguments de la méthode prepareCall servent à déterminer les types de ResultSet obtenus à partir de la
procédure. Par exemple :

String sql = "{? = call max(?, ?)}";


CallableStatement statement = connection.prepareCall(sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);

lien : Comment passer les paramètres à la procédure (IN parameter) ?


lien : Comment récupérer le résultat d'une procédure stockée (OUT parameter) ?
lien : Quels sont les différents types de ResultSet ?

- 33 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment avoir la liste de toutes les procédures stockées dans une base de données ?

Comment passer les paramètres à la procédure (IN parameter) ?


Auteurs : Ioan Calapodescu ,
Comme pour les PreparedSatement, le passage des paramètres d'entrée des CallableStatement se fait grâce à l'ensemble
des méthodes setXXX. Il est important de connaître les correspondances entre les types SQL et les types java (cf. Tableau
de relations). En plus de l'index, on peut cibler un paramètre grâce à son nom.

Voici un exemple, pour une procédure stockée chargée de retrouver les abonnés d'un annuaire ayant un certain nom.
Cette procédure renvoie plusieurs ResultSet

Le code java chargé de la créer et de l'appeler :

//CHARGEMENT DU DRIVER
Class.forName("com.mysql.jdbc.Driver");
//CONNECTION AU SGBD
String url = "jdbc:mysql://localhost/test";
String user = "user";
String password = "root";
connection = DriverManager.getConnection(url,user,password);
//CREATION DE LA PROCEDURE
Statement statement = connection.createStatement();
statement.executeUpdate("DROP PROCEDURE IF EXISTS rechercherNom");
statement.executeUpdate(
"CREATE PROCEDURE rechercherNom(IN leNom VARCHAR(50))\n"
+ "BEGIN\n"
+ " SELECT * FROM Annuaire WHERE nom = leNom;\n"
+ " SELECT COUNT(*) FROM Annuaire WHERE nom = leNom;\n"
+ "END\n");
//APPEL DE LA PROCEDURE
String sql = "{call rechercherNom(?)}";
CallableStatement call = connection.prepareCall(sql);
//passage de la chaîne "ioio" comme valeur du premier paramètre
call.setString(1,"ioio");
if(call.execute()){
//récupération des ResultSet
ResultSet resultat1 = call.getResultSet();
call.getMoreResults(Statement.KEEP_CURRENT_RESULT);
ResultSet resultat2 = call.getResultSet();
//traitement des informations
while(resultat1.next()){
for(int i=0;i<resultat1.getMetaData().getColumnCount();i++){
System.out.print(resultat1.getObject(i+1)+", ");
}
System.out.println("");
}
resultat2.next();
System.out.println("Nombre de lignes = "+resultat2.getObject(1));
resultat1.close();
resultat2.close();
}

Comme pour les PreparedStatement, les paramètres IN peuvent être identifiés par leur index dans l'instruction SQL
ou par leur nom. Pour cet exemple, les instructions ci-dessous sont équivalentes :

call.setString("leNom","ioio");
call.setObject(1,"ioio");
call.setObject(1,"ioio", Types.VARCHAR);

- 34 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

call.setObject("leNom","ioio",Types.VARCHAR);

lien : Tableau de relations


lien : Comment récupérer le résultat d'une procédure stockée (OUT parameter) ?
lien : Comment spécifier un paramètre de type INOUT ?

Comment récupérer le résultat d'une procédure stockée (OUT parameter) ?


Auteurs : Ioan Calapodescu ,
Pour récupérer les résultats (OUT) d'un CallableStatement, il faut utiliser les méthodes getXXX correspondantes au
type retourné. Les paramètres OUT doivent être enregistrés comme tel. Voici une exemple récupérant le nombre
d'abonnés d'un annuaire.

Le corps de la procédure :

CREATE PROCEDURE nombreAbonnes(OUT nb INTEGER)


BEGIN
SELECT COUNT(*) INTO nb FROM Annuaire;
END

Le code java : comme pour les paramètres d'entrée, un paramètre peux être ciblé par son nom ou par son index.

String sql = "{call nombreAbonnes(?)}";


CallableStatement statement = connection.prepareCall(sql);
//enregistrement du paramètre de sortie en fonction de son type et de son nom
statement.registerOutParameter("nb", java.sql.Types.INTEGER);
//enregistrement du paramètre de sortie en fonction de son type et de son index

//statement.registerOutParameter(1, java.sql.Types.INTEGER);
statement.execute();
//récupération du résultat en fonction de l'index
int resultat = statement.getInt(1);
//récupération du résultat en fonction du nom du paramètre

//int resultat = statement.getInt("nb");


System.out.println("Nombre d'abonnés = "+resultat);

lien : Tableau de relations


lien : Comment spécifier un paramètre de type INOUT ?

Comment spécifier un paramètre de type INOUT ?


Auteurs : Ioan Calapodescu ,
Pour spécifier un paramètre INOUT, il suffit simplement de combiner registerOutParameter et setXXX. Voici un
exemple qui montre la marche à suivre.

Voici le code java :

Connection connection = ... ;


//CREATION DE LA PROCEDURE
Statement statement = connection.createStatement();
statement.executeUpdate("DROP PROCEDURE IF EXISTS hello");
statement.executeUpdate(
"CREATE PROCEDURE hello(INOUT param VARCHAR(30))\n"
+ "BEGIN\n"

- 35 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

+ " SELECT CONCAT('Hello', param, 'avec JDBC !!!') INTO param;\n"


+ "END\n");
//APPEL DE LA PROCEDURE
String sql = "{call hello(?)}";
CallableStatement call = connection.prepareCall(sql);
//passage de la valeur du paramètre
call.setString(1, " world ");
//enregistrement du paramètre en tant que paramètre OUT
call.registerOutParameter(1, Types.VARCHAR);
//exécution et récupération du résultat
call.execute();
System.out.println(call.getString(1));

Et voici à quoi devrais ressembler le résultat :

"Hello world avec JDBC !!!"

Fameux non ? ;-)

lien : Comment passer les paramètres à la procédure (IN parameter) ?


lien : Comment récupérer le résultat d'une procédure stockée (OUT parameter) ?
lien : Comment avoir la liste de toutes les procédures stockées dans une base de données ?

Comment appeler une fonction ?


Auteurs : Ioan Calapodescu ,
L'appel d'une fonction grâce aux CallableStatement utilise la syntaxe suivante :

String sql = "{? = call nomDeLaProcedure[(?, ?, ...)]}";

Le premier paramètre doit être enregistré comme paramètre de sortie :

String sql = "?= call Hello(?)";


CallableStatement statement = connection.prepareCall(sql);
statement.registerOutParameter(1,Types.VARCHAR);
statement.setString(2,"world");
statement.execute();
System.out.println(statement.getString(1));

lien : Comment obtenir la liste des fonctions (numériques, système, etc.) ?

Comment savoir qu'un paramètre de retour(OUT) est de type SQL NULL ?


Auteurs : Ioan Calapodescu ,
Cette question a son intérêt, car bien souvent un CallableStatement va renvoyer une valeur par défaut si il rencontre
un type SQL NULL. Ce sera par exemple la chaine vide pour VARCHAR ou 0 pour INTEGER ou NUMERIC.
CallableStatement propose donc la méthode wasNull qui renvoie un boolean indiquant si le dernier paramètre de
type OUT était NULL. Cette méthode doit être utilisée seulement après l'appel de la méthode get correspondante au
paramètre de sortie. Par exemple :

String sql = "{getUnNombre(?)}";


CallableStatement statement = connection.prepareCall(sql);

- 36 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

statement.registerOutParameter(1,Types.INTEGER);
statement.execute();
int resultat = statement.getInt(1);
if(statement.wasNull()){
System.out.pritnln("Le résultat est de type SQL NULL");
}else{
System.out.println("Le résultat vaut "+resultat);
}

- 37 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les résultats - ResultSet


Qu'est-ce qu'un ResultSet ? Que sont les lignes, les colonnes et le curseur ?
Auteurs : Ioan Calapodescu ,
Les instances de l'interface ResultSet contiennent les résultats d'une requête SQL. Ils contiennent les tuples (lignes)
satisfaisant les conditions de la requête. On peut noter que les ResultSet sont des objets couramment retournés par de
nombreuses méthodes des classes appartenant aux packages java.sql et javax.sql. Cette utilisation se voit nottament
dans les interfaces de méta-données, qui renvoient beaucoup d'informations sous forme de ResultSet (Cf.Que sont les
méta-données ? ).

La structure des ResultSet est très semblable à celle d'une Table dans une base de données relationnelles. C'est à dire :

• Les colonnes (column) : Ce sont les éléments verticaux de la table (ou ResultSet). Ils symbolisent les attributs
des différents enregistrements de la table. Ils sont caractérisés par un nom et un domaine dans lequel ils puisent
leurs valeurs (par exemple pour les entiers INTEGER ou VARCHAR pour les chaînes de caractères).
• Les lignes (row) : Ce sont les éléments horizontaux de la table. on les nomme aussi tuples ou n-uplets. Ils sont les
différents enregistrements contenus dans la table (ou ResultSet). Chaque ligne renseigne les attributs définis par
les colonnes.
• Le curseur (cursor) : Cet objet pointe sur une "ligne". Cette ligne peux être soit une ligne comme définie ci-
dessus (contenant les données), soit une ligne spéciale comme afterLast, insertRow, etc... C'est le curseur qui
permet le déplacement dans le ResultSet, pour l'accès aux différents enregistrements.

Voir Quels sont les différents types de ResultSet ?, Comment parcourir un ResultSet ? et Comment retrouver les valeurs
contenues dans un ResultSet ? pour plus d'informations.

lien : Comment créer un Statement ?


lien : Quels sont les différents types de ResultSet ?
lien : Comment parcourir un ResultSet ?
lien : Comment retrouver les valeurs contenues dans un ResultSet ?
lien : Que sont les méta-données ?

Quels sont les différents types de ResultSet ?


Auteurs : Ioan Calapodescu ,
Le "type" d'un ResultSet est définis lors de la création de l'instruction (Statement, PreparedStatement ou
CallableStatement). Les "type" d'un ResultSet est définis par trois caractéristiques, qui définissent les possibilités de
déplacement, les possibilités de mise à jour et le maintien des curseurs lors des transactions. Par curseur, on entendra
ici le ResultSet lui même.

Les méthodes , createStatement, prepareStatement et prepareCall, présentent toutes trois la possibilité de spécifier ces
attributs.

Statement createStatement(int resultSetType,


int resultSetConcurrency,
int resultSetHoldability)
PreparedStatement prepareStatement(String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
CallableStatement prepareCall(String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)

- 38 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Voici la liste des différents arguments acceptés :

Pour les possibilités de déplacement (int resultSetType) :

• ResultSet.TYPE_FORWARD_ONLY : C'est la valeur par défaut (et la seule possible pour JDBC 1.0). Elle
indique que les déplacements du curseur ne peuvent se faire "qu'en avant" (de la première à la dernière ligne).
Une fois la dernière ligne atteinte (la méthode last renvoyant true) le ResultSet est fermé et les données ne sont
plus accessibles.
• ResultSet.TYPE_SCROLL_INSENSITIVE : Cette valeur indique que le curseur peut être déplacé dans
les deux sens, mais aussi arbitrairement (de manière absolue ou relative). Le terme insesitive indique que le
ResultSet est insensible aux modifications des valeurs dans la base de données. Cela définit en fait une vue
statique des données contenues dans le ResultSet.
• ResultSet.TYPE_SCROLL_SENSITIVE : Cette valeur indique que le curseur peut être déplacé dans les deux
sens, mais aussi arbitrairement (de manière absolue ou relative). Le terme sesitive indique que le ResultSet
est sensible aux modifications des valeurs dans la base de données. Cela définit en fait une vue dynamique des
données contenues dans le ResultSet.

Pour les possibilités de mise à jour (int resultSetConcurrency) :

• ResultSet.CONCUR_READ_ONLY : C'est la valeur par défaut (et la seule possible pour JDBC 1.0). Elle
indique que les données contenues dans le ResultSet ne peuvent qu'être lues.
• ResultSet.CONCUR_UPDATABLE : Cette valeur indique que l'on peut modifier les données de la base via le
ResultSet.

Pour le maintien des curseurs (int resultSetHoldability) :

• ResultSet.HOLD_CURSORS_OVER_COMMIT : Les objets ResultSet ne sont pas fermés. Ils restent ouverts
lorsqu'une validation est effectuée implicitement ou explicitement.
• ResultSet.CLOSE_CURSORS_AT_COMMIT : Les objets ResultSet sont fermés lorsqu'une validation est
effectuée implicitement ou explicitement.

lien : Comment déplacer le curseur sur une ligne précise ?


lien : Comment parcourir un ResultSet ?
lien : Comment mettre à jour un ResultSet ?

Comment retrouver les valeurs contenues dans un ResultSet ?


Auteurs : Ioan Calapodescu ,
Pour retrouver les valeurs contenues dans les lignes d'un ResultSet, on a à notre disposition une dizaine de méthode
getXXX. Un exemple vaut mieux qu'un long discours :

Voici la structure de la table étudiée :

CREATE TABLE MaTable (


id INTEGER PRIMARY KEY,
nom VARCHAR(50),
prix DECIMAL,
date DATE
)

Voici le code java permettant de récupérer toutes les valeurs contenues dans celle-ci :

- 39 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Statement statement = connection.createStatement(


ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM MaTable";
ResultSet resultat = statement.executeQuery(sql);
while(resultat.next()){
int id = resultat.getInt(1);
String nom = resultat.getString(2);
double prix = resultat.getDouble(3);
java.sql.Date date = resultat.getDate(4);
int row = resultat.getRow();
System.out.println("Données contenues dans la ligne "+row);
System.out.println("id : "+id+" nom : "+nom+
" prix : "+prix+" date : "+date);
}

Comme pour les paramètre de retour d'une procédure stockée, on peut récupérer une valeur en fonction de son index,
mais aussi en fonction de son nom. Le code suivant est donc équivalent à celui ci-dessus :

int id = resultat.getInt("id");
String nom = resultat.getString("nom");
double prix = resultat.getDouble("prix");
java.sql.Date date = resultat.getDate("date");

On peut noter que les méthodes getString et getObject sont des méthodes génériques qui peuvent être employées quelque
soit le type SQL de la valeur recherchée.

Pour connaître les correspondances entre les types java et les types SQL, regardez : Tableau de relations.

lien : Comment savoir si une valeur correspond au type SQL NULL ?


lien : Tableau de relations
lien : Comment récupérer les types SQL et Java des colonnes d'un ResultSet ?

Comment obtenir la valeur la plus récente d'une ligne ?


Auteurs : Ioan Calapodescu ,
ResultSet nous propose la méthode refreshRow pour mettre à jour les valeurs contenues dans une ligne donnée. Cette
fonctionnalité peut-être intéressante lors de traitements longs pendant lesquels les données sont susceptibles de changer
(à cause d'autres utilisateurs par exemple).

Statement statement = connection.createStatement(


ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM MaTable";
ResultSet resultat = statement.executeQuery(sql);
resultat.first();
//on récupère le "prix" de la première ligne
double d1 = resultat.getDouble("prix");
//un traitement quelconque
resultat.fisrt();
//on vérifie que le prix n'a pas changé durant le traitement
resultat.refreshRow();
double d2 = resultat.getDouble("prix");
if(d1!=d2){
//le prix a changé
}

- 40 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

NB : naturellement cette fonctionnalité n'est disponible que pour les ResultSet vérifiant
ResultSet.TYPE_SCROLL_SENSITIVE.

lien : Comment retrouver les valeurs contenues dans un ResultSet ?

Comment savoir si une valeur correspond au type SQL NULL ?


Auteurs : Ioan Calapodescu ,
Comme pour les paramètres de retour des procédures stockées, les ResultSet renvoient des valeurs par défaut lorsqu'ils
rencontrent une valeur SQL NULL. Pour vérifier que 0 ou la chaîne vide ne sont pas en fait de type SQL NULL, il
faut utiliser la méthode wasNull.

Statement statement = connection.createStatement(


ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM MaTable";
ResultSet resultat = statement.executeQuery(sql);
while(resultat.next()){
double prix = resultat.getDouble(3);
String text = (resultat.wasNull())?"pas de prix spécifié(NULL)":String.valueOf(prix);
System.out.println(" prix : "+txt);

La méthode wasNull doit être appelée juste après l'appel de la méthode getXXX correspondante.

lien : Comment savoir qu'un paramètre de retour(OUT) est de type SQL NULL ?
lien : Comment retrouver les valeurs contenues dans un ResultSet ?

Comment parcourir un ResultSet ?


Auteurs : Ioan Calapodescu ,
L'interface ResultSet fourni plusieurs méthodes pour parcourir les données. Ces différentes méthodes sont bien sûr
disponibles selon le type de ResultSet. Notons, qu'au contraire de la plupart des structures de données en java (tableaux,
vector, List, etc.) les index des lignes commencent à 1.

• next : passe le curseur à l'élément suivant


• previous : passe le curseur à l'élément précédent
• first : passe le curseur sur le premier élément
• last : passe le curseur sur le dernier élément
• beforeFirst : passe le curseur avant le premier élément (position par défaut du curseur)
• afterLast : passe le curseur après le dernier élément

Voici un exemple :

Connection connection = DriverManager.getConnection(url,user,password);


Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE
,ResultSet.CONCUR_READ_ONLY);
ResultSet resultat = statement.executeQuery("SELECT * FROM MaTable");
System.out.println(resultat.isbeforeFirst());
//true
resultat.next();
//on se retrouve ici sur la première ligne

//traitement de la première ligne ...


while(resultat.next()){

- 41 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

//traitement des autres lignes


}
resultat.first();
//on a replacé ici le curseur sur la première ligne
resultset.afterlast();
//on a replacé le curseur après la dernière ligne
while(resultat.previous()){
// on parcours ici le ResultSet de la dernière à la première ligne
}
//etc.

Il existe quatre autres méthodes relatives aux déplacements, voir : Comment déplacer le curseur sur une ligne précise ?
et Comment insérer une ligne dans un ResultSet ? . NB : Ces différentes méthodes peuvent lever une SQLException si
le type de mouvement n'est pas autorisé, ou si le ResultSet est fermé.

lien : Comment déplacer le curseur sur une ligne précise ?


lien : Comment insérer une ligne dans un ResultSet ?
lien : Comment connaître la position du curseur ?

Comment déplacer le curseur sur une ligne précise ?


Auteurs : Ioan Calapodescu ,
En dehors des méthodes first, beforeFirst, last et afterlast, ResultSet propose quatre autres méthodes relatives au
positionnement du curseur. Les deux premières, absolute et relative, permettent de mouvoir le curseur sur une ligne
précise, soit de manière absolue (en indiquant un numéro de ligne), soit de manière relative à la ligne actuellement
pointée.

Connection connection = DriverManager.getConnection(url,user,password);


Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE
,ResultSet.CONCUR_READ_ONLY);
ResultSet resultat = statement.executeQuery("SELECT * FROM MaTable");
resultat.next();
//on se trouve ici sur la première ligne
resultat.absolute(40);
//on se trouve ici sur la 40 ème ligne
resultat.absolute(1);
//on se trouve sur la première ligne == resultat.first()
resultat.absolute(-1);
//on se trouve sur la dernière ligne == resultat.last()
resultat.absolute(-2);
//on se trouve sur l'avant dernière ligne == resultat.last()+reusultat.previous()
resultat.first();
//on reviens sur la première ligne
resultat.relative(1);
//on se trouve sur la seconde ligne == resultat.next();
resultat.relative(50);
//on se trouve sur la 52 ème ligne
resultat.relative(-1);
//on se trouve sur la 51 ème ligne == resultat.previous()

Ces méthodes lèvent naturellement une SQLException si le ResultSet est de type SCROLL_FORWARD_ONLY ou si
la valeur passée en paramètre est en dehors des limites.

lien : Comment parcourir un ResultSet ?


lien : Comment connaître la position du curseur ?

- 42 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment insérer une ligne dans un ResultSet ?

Comment connaître la position du curseur ?


Auteurs : Ioan Calapodescu ,
ResultSet propose la méthode int getRow() qui récupère l'index du curseur. De plus, les méthodes isFirst, isLast,
isBeforeFirst et isAfterLast nous permettent de déterminer des positions bien précises du curseur.

Voici le corps d'une méthode nous permettant de déterminer la position du curseur :

public void afficherInfosCurseur(ResultSet resultat) throws SQLException{


String curseur = "row = "+resultat.getRow();
if(resultat.isBeforeFirst()){
curseur += "(avant la première ligne)";
}
if(resultat.isAfterLast()){
curseur += "(après la dernière ligne)";
}
if(resultat.isFirst()){
curseur += "(première ligne)";
}
if(resultat.isLast()){
curseur += "(dernière ligne)";
}
System.out.println(curseur);
}

Voici un code de test :

Statement statement = connection.createStatement(


ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM Annuaire";
ResultSet resultat = statement.executeQuery(sql);
afficherInfosCurseur(resultat);
//on parcours le ResultSet de la première à la dernière ligne
while(resultat.next()){
afficherInfosCurseur(resultat);
}
afficherInfosCurseur(resultat);
//on parcours le ResultSet de la dernière à la première ligne
while(resultat.previous()){
afficherInfosCurseur(resultat);
}
afficherInfosCurseur(resultat);
//quelques mouvements absolus
resultat.absolute(-1);
afficherInfosCurseur(resultat);
resultat.absolute(1);
afficherInfosCurseur(resultat);
//quelques mouvements relatifs
resultat.relative(5);
afficherInfosCurseur(resultat);
resultat.relative(-3);
afficherInfosCurseur(resultat);
resultat.relative(-3);
afficherInfosCurseur(resultat);

qui pour un ResultSet de 8 lignes devrait vous donner ce résultat :

- 43 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

row = 0(avant la première ligne)


row = 1(première ligne)
row = 2
//...
row = 7
row = 8(dernière ligne)
row = 0(après la dernière ligne)
row = 8(dernière ligne)
row = 7
//...
row = 2
row = 1(première ligne)
row = 0(avant la première ligne)
row = 8(dernière ligne)
row = 1(première ligne)
row = 6
row = 3
row = 0(avant la première ligne)

lien : Comment parcourir un ResultSet ?


lien : Comment connaître la position du curseur ?

Comment mettre à jour un ResultSet ?


Auteurs : Ioan Calapodescu ,
Les ResultSet vérifiant ResultSet.CONCUR_UPDATABLE peuvent être mis à jour. Pour mettre à jour plusieurs
méthodes update sont à notre disposition. Les premières sont de la forme updateXXX ou XXX est le type de la donnée
devant être mise à jour. La dernière est updateRow qui permet la mise à jour effective de la ligne visée. Par exemple :

Connection connection = ...;


//création d'un instruction renvoyant des résultats

//pouvant être mis à jour


Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
//on séléctionne tous les tuples de la Table Annuaire
String sql = "SELECT * FROM Annuaire";
ResultSet resultat = statement.executeQuery(sql);
// on se place sur le premier tuple récupéré
resultat.first();
//on récupère la valeur de la colonne "nom"
String nom1 = resultat.getString("nom");
//on met à jour la valeur de la colonne "nom"
resultat.updateString("nom", "nouveauNom");
//on met à jour la valeur dans la table
resultat.updateRow();
String nom2 = resultat.getString("nom");
System.out.println("Ancien nom = "+nom1+
"Nouveau nom = "+nom2);

Pour annuler les mises à jour du ResultSet on peut utiliser la méthode cancelRowUpdates. Cette méthode ne marche
que si elle est appelée avant la méthode updateRow.

Si vous changez la position du curseur avant l'appel de la méthode updateRow, toutes les mise à jour sont perdues.

- 44 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Les méthodes updateXXX (ou XXX indique le type des données) sont aussi utilisées lors de l'insertion de nouvelles
lignes dans le ResultSet.

lien : Comment insérer une ligne dans un ResultSet ?

Comment insérer une ligne dans un ResultSet ?


Auteurs : Ioan Calapodescu ,
Pour insérer une nouvelle ligne dans un ResultSet, il faut d'abord positionner le curseur avec la méthode
moveToInsertRow. Ensuite, il faut définir les valeurs de la nouvelle ligne avec les méthodes updateXXX (ou XXX indique
le type des données). Finalement, il faut faire appel à la méthode insertRow, qui insérera la nouvelle ligne.

Connection connection = ...;


Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM Annuaire";
ResultSet resultat = statement.executeQuery(sql);
// on se place sur la ligne à insérer
resultat.moveToInsertRow();
//on renseigne les différents champs
resultat.updateInt("id",456);
resultat.updateString("nom","nouveauNom");
resultat.updateString("prenom","nouveauPrenom");
//on insère effectivement la nouvelle ligne
resultat.insertRow();

La méthode moveToCurrentRow permet de se replacer sur la ligne pointée avant l'appel à moveToInsertRow.

lien : Comment parcourir un ResultSet ?


lien : Comment déplacer le curseur sur une ligne précise ?
lien : Comment mettre à jour un ResultSet ?

Doit on fermer un ResultSet ?


Auteurs : Ioan Calapodescu ,
Le problème est le même que pour une Connection ou un Statement. Un ResultSet sera automatiquement fermé lors de
la fermeture du Statement dont il dépends. Cependant, il est conseillé de le fermer explicitement.

Connection connection = null;


Statement statement = null;
ResultSet resultat = null;
try{
//initialisation des trois éléments
//divers traitements sur la base de données
}
catch(Exception){
//gestion des différents types d'erreur pouvant survenir
}
finally{
try{if(resultat!=null){resultat.close();}}catch(Exception e){}
try{if(statement!=null){statement.close();}}catch(Exception e){}
try{if(connection!=null){connection.close();}}catch(Exception e){}

- 45 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment fermer une connexion ?


lien : Doit on fermer un Statement ?

Comment connaître les caractéristiques (type) d'un ResultSet depuis le programme ?


Auteurs : Ioan Calapodescu ,
L'interface ResultSet met à notre disposition toutes les méthodes nécessaires pour découvrir, depuis le programme,
les caractéristiques de ceux-ci. On peux aussi utiliser le Statement correspondant au ResultSet pour obtenir ces
informations. Par exemple :

public void afficherCaracteristiques(ResultSet resultat)throws SQLException{


int type = resultat.getType();
//ou a partir du Statement

//int type = resultat.getStatement().getResultSetType();


int concurrency = resultat.getConcurrency();
//ou a partir du Statement

//int concurrency = resultat.getStatement().getResultSetConcurrency();


int holdability = resultat.getStatement().getResultSetHoldability();
String sType = "";
String sConcurrency = "";
String sHoldability = "";
switch(type){
case ResultSet.TYPE_FORWARD_ONLY:
sType = "Type : FORWARD_ONLY";
break;
case ResultSet.TYPE_SCROLL_INSENSITIVE:
sType = "Type : SCROLL_INSENSITIVE";
break;
case ResultSet.TYPE_SCROLL_SENSITIVE:
sType = "Type : SCROLL_SENSITIVE";
break;
default :
sType = "Type inconnu ??? Bug ???";
break;
}
switch(concurrency){
case ResultSet.CONCUR_READ_ONLY:
sConcurrency = "Concurrency : CONCUR_READ_ONLY";
break;
case ResultSet.CONCUR_UPDATABLE:
sConcurrency = "Concurrency : CONCUR_UPDATABLE";
break;
default :
sConcurrency = "Concurrency inconnue ??? Bug ???";
break;
}
switch(holdability){
case ResultSet.HOLD_CURSORS_OVER_COMMIT :
sHoldability = "Holdability : HOLD_CURSORS_OVER_COMMIT";
break;
case ResultSet.CLOSE_CURSORS_AT_COMMIT:
sHoldability = "Holdability : CLOSE_CURSORS_AT_COMMIT";
break;
default :
sHoldability = "Holdability inconnue ??? Bug ???";
break;
}
System.out.println("Les caractéristiques de ce ResultSet sont : ");
System.out.println(sType);

- 46 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

System.out.println(sConcurrency);
System.out.println(sHoldability);
}

lien : Quels sont les différents types de ResultSet ?

Comment supprimer une ligne dans un ResultSet ?


Auteurs : Ioan Calapodescu ,
Pour supprimer une ligne dans un ResultSet il suffit d'utiliser la méthode deleteRow. Par exemple pour supprimer la
ligne 32 d'un ResultSet, on pourrais faire comme ceci :

ResultSet resultat = ...;


resultat.absolute(32);
resultat.deleteRow();

On peux par exemple complètement vider une table comme ceci :

Connection connection = ...;


Statement statement = connection.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM MaTable";
ResultSet resultat = statement.executeQuery(sql);
while(resultat.next()){
resultat.deleteRow();
System.out.println("row : "+resultat.getRow());
System.out.println(" deleted : "+resultat.rowDeleted());
}

lien : Comment insérer une ligne dans un ResultSet ?


lien : Qu'est-ce que JDBC ?

Comment retrouver l'index d'une colonne à partir de son nom ?


Auteurs : Ioan Calapodescu ,
Pour retrouver l'index d'une colonne à partir de son nom, on peut utiliser la méthode findColumn(String nom). Par
exemple :

ResultSet resultat = ...;


String nom = "nomDeLaColonne";
int index = resultat.findColumn(nom);
System.out.println("La colonne "+nom+" a pour index "+index);

Cette méthode est susceptible de lever une SQLException si aucune colonne ne correspond au nom passé en paramètre.

- 47 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

NB : pour faire l'opération inverse, c'est à dire retrouver le nom d'une colonne à partir d'un index, il est nécessaire
de passer par ResultSetMetaData.

Que sont les fetch size et fetch direction ?


Auteurs : Ioan Calapodescu ,
Les fetch size et fetch direction sont des caractéristiques des ResultSet.

Oui, mais qu'est-ce que c'est ?


Fetch size et fetch direction représentant respectivement le nombre de lignes que le driver devra garder en mémoire
lors d'une reqûete et la "direction" de traitement de ces lignes.
Pour bien comprendre ce que désigne la fetch size, on va prendre l'exemple d'une requête retournant plusieurs milliers
de lignes. Dans ce cas, l'intégralité des données n'est pas gardée en mémoire par le ResultSet. Les données sont gardées
en mémoire par "blocs". Une fois qu'un bloc est parcouru (avec la méthode next(), par exemple), le driver va chercher
le bloc suivant. Et ainsi de suite jusqu'au traitement complet des données. La taille de ces blocs est tout simplement
la fetch size.
Attention, ces deux valeurs sont seulement des indications données au driver. En pratique, selon les implémentations,
le driver peut en tenir compte ou non.

Comment récupérer ces valeurs ?


Vous pouvez récupérer ces valeurs grâce aux méthodes getFetchSize et getFetchDirection de l'interface ResultSet.
Pour récupérer les valeurs par défaut (indiquées par le driver), vous pouvez utiliser les mêmes méthodes, mais de
l'interface Statement.

Comment indiquer ces valeurs ?


Vous pouvez indiquer les valeurs de fetch size et fetch direction avec les méthodes setFetchSize et setFetchDirection.
Pour la méthode setFetchSize, le paramètre à indiquer est le nombre de lignes (int) que le driver devra chercher. Une
SQLException est levée si ce paramètre est strictement inférieur à 0 ou supérieur à Statement.getMaxRows(). Dans le
cas ou ce paramètre vaut 0, le driver décide lui même du nombre de lignes à garder en mémoire.
Pour la méthode setFetchDirection, le paramètre à indiquer est un de ceux-ci : ResultSet.FETCH_FORWARD,
ResultSet.FETCH_REVERSE, ou ResultSet.FETCH_UNKNOWN.
Vous pouvez aussi utiliser ces deux méthodes, mais dans la classe Statement, pour indiquer les valeurs par défaut à
utiliser pour les ResultSet créés.

- 48 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet

- 49 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet > Généralités


Qu'est ce qu'un RowSet ?
Auteurs : Ioan Calapodescu ,
L'interface RowSet est une extension de ResultSet. Comme sa super-interface, RowSet représente un ensemble de
données tabulaires. Le but de cette interface est d'ajouter aux ResultSet : facilité d'utilisation, flexibilité et indépendance.

Facilité d'utilisation et flexibilité :

Le principal avantage des RowSet est le fait qu'ils ajoutent à l'API JDBC toute la puissance des JavaBeans. Ce qui
signifie des facilités pour :

• La gestion des propriétés : On peut facilement configurer un RowSet grâce à un ensemble de méthodes setXXX.
Ces méthodes permettent, par exemple, de spécifier le nom de l'utilisateur, l'url de connexion ou encore une
commande (instruction) SQL.
• La géstion des événements : Les RowSetListener peuvent se mettre à l'écoute des événements relatifs aux
RowSet.

Indépendance :

L'indépendance se fait sur deux points :

• Par rapport à l'API : Tous les types de RowSet sont capables de se connecter et de lancer une instruction SQL.
Il n'est plus nécessaire de passer explicitement par une Connection ou un Statement.
• Par rapport au matériel utilisé : Tous les types de RowSet peuvent être mis à jour et permettent n'importe quel
mouvement du curseur. Donc, vous pourrez utiliser ces fonctionnalités même si la base de données ou le driver
ne les fournissent pas directement.

lien : Quels sont les différentes catégories de RowSet ?

Quels sont les différentes catégories de RowSet ?


Auteurs : Ioan Calapodescu ,
On peux séparer les différents RowSet en deux catégories principales : les connectés et les déconnectés. En voici les
caractéristiques :

• Connectés : En dehors des propriétés générales des RowSet, leur fonctionnement est identique à celui d'un
ResultSet. C'est à dire que ceux ci gardent une connexion ouverte vers le SGBD durant tout leur cycle de vie.
• Déconnectés : Les RowSet de cette catégorie sont capables de rompre la connexion à la source, faire des
modifications sur les données puis de se reconnecter afin de transmettre les modifications, tout en gérant un
éventuel conflit.

lien : Qu'est ce qu'un RowSet ?

- 50 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment fonctionnent les RowSet déconnectés ?

Quelles sont les implementations proposées par Sun ?


Auteurs : Ioan Calapodescu ,
Sun propose cinq interfaces filles de RowSet et leurs implémentations. On pourra remarquer que si RowSet fait partie
du package javax.sql, les autres types font partie du package javax.sql.rowset (disponible seulement depuis la version
1.5 de java). Voici les différents types de RowSet, leurs caractéristiques et leurs avantages.

• RowSet : super-interface de tous les autres types. Définie depuis JDBC 2.0.
• CachedRowSet : RowSet déconnecté stockant ses données en mémoire. Il n'est pas particulièrement adapté à de
grandes quantités de données. Par contre, il est parfaitement adapté pour fournir aux clients légers (comme les
PDA (Personal Digital Assistant) ou les téléphones portables) des données tabulaires, provenant d'une base de
données.
• WebRowSet : RowSet déconnecté. Particulièrement adapté aux applications web, grâce à sa faculté de lire
(écrire) ses données à partir (sous forme) de fichiers XML ou de flux de données.
• FilteredRowSet : RowSet déconnecté. Permettent de filtrer les données présentées à l'utilisateur grâce à la classe
Predicate.
• JoinRowSet : RowSet déconnecté. Permettent de réaliser facilement des JOIN à partir de toute classe ou
interface implémentant Joinable.
• JdbcRowSet : RowSet connecté. C'est une enveloppe légère autour d'un ResultSet permettant de faire du driver
JDBC un bean java.

Pour note : toutes ces interfaces étendent aussi javax.sql.rowset.Joinable.

Comment créer, configurer et peupler un RowSet ?


Auteurs : Ioan Calapodescu ,
Il y a généralement trois étapes rencontrées durant la création d'un RowSet. La première de ces étapes est l'obtention
d'une instance du RowSet désiré. Viens ensuite la spécification des propriétés de l'instance. Enfin, il ne reste plus qu'à
"peupler" ce RowSet, c'est à dire le remplir des données souhaitées.

Voici deux cas de figure :

.
//CHARGEMENT DU DRIVER
Class.forName("com.mysql.jdbc.Driver");
//CREATION DE LA CONNEXION
String url = "jdbc:mysql://localhost/maBase";
String user = "utilisateur";
String password = "motDePasse";
connection = DriverManager.getConnection(url,user,password);
//RECUPERATION D'UN RESULTSET
Statement statement = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM Annuaire";
ResultSet resultat = statement.executeQuery(sql);
//CREATION D'UN ROWSET
CachedRowSet rowset = new CachedRowSetImpl();
//propriétés du RowSet
rowset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
rowset.setConcurrency(ResultSet.CONCUR_UPDATABLE);
//peuplement du RowSet avec les données du ResultSet
rowset.populate(resultat);

- 51 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

//FERMETURE DE LA CONNECTION
connection.close();
System.out.println(connection.isClosed());
//FINALEMENT TRAITEMENT DES DONNEES HORS CONNECTION
while(rowset.previous()){

On peut remarquer, dès ce premier exemple, plusieurs avantages de RowSet.

• La facilité de remplissage du RowSet : la simple ligne rowset.populate(resultat) permet de peupler le RowSet


avec les données contenues dans le ResultSet.
• La possibilité de travailler hors connexion : ici le traitement se fait après la fermeture de la connexion.
• Une plus grande indépendance par rapport à la base et au pilote : même si le ResultSet ne peux pas être mis à
jour (ou si le pilote ne permets pas cette option), le RowSet créé lui le sera.

.
//CREATION DU ROWSET
JdbcRowSet rowset = new JdbcRowSetImpl();
//MISE EN PLACE DES DIFFERENTES PROPRIETES
String url = "jdbc:mysql://localhost/MaBase";
String user = "utilisateur";
String password = "motDePasse";
String command = "SELECT * FROM Annuaire WHERE nom = ?";
//propriétés nécessaires à la connexion
rowset.setUrl(url);
rowset.setUsername(user);
rowset.setPassword(password);
//propriétés nécessaires à l'exécution
rowset.setCommand(command);
rowset.setString(1,"unNom");
//EXECUTION DU ROWSET POUR LE PEUPLER
rowset.execute();
//puis traitement des différentes données

Ce second exemple met en évidence plusieurs autres facilités :

• Plus besoin de créer explicitement une Connection.


• Plus besoin de créer explicitement un Statement.
• Facilité du passage d'arguments à l'instruction SQL (plus de passage par un PreparedStatement et la syntaxe
d'échappement).

lien : Comment utiliser, parcourir et modifier un RowSet ?

Comment utiliser, parcourir et modifier un RowSet ?


Auteurs : Ioan Calapodescu ,
L'utilisation des RowSet est, quasiment en tous points, identique à celle des ResultSet. Cela implique les mouvements
du curseur, la récupération des données et l'étude des méta-données. Une des seules différences notables se fait lors de
la mise à jour des données pour les RowSet déconnectés (Cf. la partie dédiée). Voici un exemple utilisant JdbcRowSet :

try{
//CHARGEMENT DU DRIVER
Class.forName("com.mysql.jdbc.Driver");
//CREATION D'UN ROWSET
JdbcRowSet rowset = new JdbcRowSetImpl();
//propriétés du RowSet
rowset.setUrl("jdbc:mysql://localhost/maBase");

- 52 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

rowset.setUserName("utilisateur");
rowset.setPassword("motdePasse");
rowset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
rowset.setConcurrency(ResultSet.CONCUR_UPDATABLE);
rowset.setCommand("SELECT nom, prenom FROM Annuaire");
//execution et peuplement du RowSet
rowset.execute();
//TRAITEMENT DES DONNEES
rowset.last();
//parcours des résultats du dernier au premier tuple
while(rowset.previous()){
System.out.println("Nom = "+rowset.getObject("nom")+
" Prenom = "+rowset.getString(2));
}
//modification de la colonne d'index 1 de la première ligne
rowset.first();
rowset.updateString(1,"modification");
rowset.updateRow();
//positionnement sur la seconde ligne et suppression de celle-ci
rowset.relative(1);
rowset.deleteRow();
//insertion d'une nouvelle ligne
rowset.moveToInsertRow();
rowset.updateString("prenom", "un nouveau prénom");
rowset.updateString("nom", "un nouveau nom");
rowset.insertRow();
rowset.moveToCurrentRow();
//etc.

lien : Comment parcourir un ResultSet ?


lien : Comment retrouver les valeurs contenues dans un ResultSet ?
lien : Comment mettre à jour un ResultSet ?
lien : Comment valider les modifications d'un RowSet déconnecté ?

Comment se mettre à l'écoute des modifications d'un RowSet ?


Auteurs : Ioan Calapodescu ,
Un nouveau type de listener est disponible dans le package javax.sql : RowSetListener. On peux ajouter ou supprimer
un tel type de listener à un RowSet grâce aux méthodes addRowSetListener et removeRowSetListener. Par exemple :

rowset.addRowSetListener(new RowSetListener(){
public void cursorMoved(RowSetEvent rse){
System.out.println("Le curseur à bougé\n"+rse);
}
public void rowChanged(RowSetEvent rse){
System.out.println("Une ligne du RowSet à changé\n"+rse);
}
public void rowSetChanged(RowSetEvent rse){
System.out.println("Le RowSet a complétement changé\n"+rse);
}
});

- 53 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet > Les RowSet déconnectés (CachedRowSet, etc.)
Comment fonctionnent les RowSet déconnectés ?
Auteurs : Ioan Calapodescu ,
Les RowSet déconnectés ne se connectent à la source des données que lorsqu'ils ont besoin de lire ou écrire dans celle-
ci. Le reste du temps ils sont déconnectés de la source. Pour pouvoir se connecter ils passent par l'intermédiaire d'un
SyncProvider. Cette classe abstraite du package javax.sql.rowset.spi oblige à définir, entre autres, un RowSetReader
et un RowSetWriter. Ce sont ces deux interfaces qui définissent l'écriture et la lecture de la source de données.

Les implementations de Sun utilisent une instance de com.sun.rowset.providers.RIOptimisticProvider. Mais, on peut


utiliser d'autres implementations. Les SyncProvider, un peu à la manière des drivers, doivent être enregistrés auprès
de SyncFactory. Par exemple :

String nom = "mon.implementation.de.MonSyncProvider";


//nom complet de la classe
SyncFactory.registerProvider(nom);
//enregistrement du provider

Les RowSet déconnectés peuvent spécifier leur provider de deux façons :

String nom = "mon.implementation.de.MonSyncProvider";


//grâce au constructeur
CachedRowSet rowset = new CachedRowSetImpl(nom);
//ou grâce à la méthode setSyncProvider
CachedRowSet autreRowset = new CachedRowSetImpl();
autreRowset.setSyncProvider(nom);

lien : Comment reconnecter un RowSet déconnecté ?

Comment reconnecter un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
La connexion ou reconnexion à la source des données se fait de manière totalement invisible pour l'utilisateur. Celle-
ci se fait lors de l'appel aux méthodes execute et acceptChanges. Toute fois, vous devez toujours vérifier que les trois
propriétés suivantes sont définies : user, password et url. Par exemple, si vous peuplez un CachedRowSet grâce à un
ResultSet ces propriétés ne sont pas "transmises". Voici un code qui pourrais poser problème :

String url = "jdbc:mysql://host/maBase";


String user = "user";
String password = "pass";
Connection connection = DriverManager.getConnection(url,user,password);
//RECUPERATION D'UN RESULTSET
Statement statement = connection.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String sql = "SELECT * FROM MaTable";
ResultSet resultat = statement.executeQuery(sql);
//CREATION D'UN ROWSET
CachedRowSet rowset = new CachedRowSetImpl();
rowset.populate(resultat);
//modification des données

//...

//fin des modifications

- 54 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

rowset.setUrl(url);
rowset.setUserName(user);
rowset.setPassword(pass);
//sans ces trois lignes un appel à acceptChanges lèverais une exception

Si vous ne voulez pas passer ces trois propriétés, les méthodes acceptChanges et execute peuvent être appelées avec une
Connection en paramètre. Vous n'aurez pas à vous soucier de la fermeture de celle-ci, les méthodes le feront à votre
place. Par exemple :

String url = "jdbc:mysql://host/maBase";


String user = "user";
String password = "pass";
CachedRowSet rowset = new CachedRowSetImpl();
rowset.setCommand("SELECT * FROM MaTable WHERE id = ?");
rowset.setInt(1,12345);
rowset.execute(DriverManager.getConnection(url,user,password));

lien : Comment valider les modifications d'un RowSet déconnecté ?

Comment valider les modifications d'un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
N'étant pas continuellement connectés à la source, les RowSet déconnectés nécessitent l'appel d'une méthode
supplémentaire pour valider leurs modifications. Il faut appeler la méthode acceptChanges pour transmettre les
modifications internes au RowSet à la source. Cela est valable pour tout type de modification : INSERT, UPDATE,
DELETE, etc. Par exemple :

CachedRowSet rowset = new CachedRowSetImpl();


//propriétés nécessaires à la connexion
rowset.setUrl("jdbc:mysql://localhost/MaBase");
rowset.setUsername("user");
rowset.setPassword("pass");
//propriétés de la commande SQL
rowset.setCommand("SELECT id, nom, prenom FROM Annuaire");
rowset.execute();
//modification des données
if(rowset.first()){
rowset.updateString("nom", "nouveau nom pour la première ligne");
rowset.updateRow();
}
rowset.moveToInsertRow();
rowset.updateInt("id",456);
rowset.updateString("nom", "un nouveau nom");
rowset.updateString("prenom", "un nouveau prénom");
rowset.insertRow();
rowset.moveToCurrentRow();
//à ce stade seulement les données du RowSet on été modifiées

//la base contient toujours les données

//il faut valider les modifications en appellant acceptChanges


rowset.acceptChanges();

lien : Comment gérer les conflits durant la validation des modifications ?


lien : Comment détecter les modifications d'un RowSet déconnecté ?

- 55 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment annuler les modifications d'un RowSet déconnecté ?

Comment gérer les conflits durant la validation des modifications ?


Auteurs : Ioan Calapodescu ,
La validation des modifications, des RowSet déconnectés, est susceptible de poser des problèmes de conflits. Cela peut-
être le cas si un tiers à déjà modifié une valeur de la base de données. La difficulté est donc de savoir laquelle des
modifications est prioritaire. Laquelle doit être inscrite définitivement dans la base ?

L'implementation de base, RIOptimisticProvider, doit son nom au fait qu'elle suit le modèle d'accès concurrentiel
optimiste. C'est-à-dire qu'aucun verrou n'est posé sur les données et qu'elles peuvent être modifiées à tout moment
par d'autres utilisateurs (ou programmes). En cas de détection de conflit les modifications ne sont tout simplement pas
validées. Par contre, acceptChanges lève une javax.sql.rowset.spi.SyncProviderException (fille de SQLException).

Les SyncProviderException permettent l'accès à un SyncResolver qui permet de gérer les conflits.

CachedRowSet rowset = new CachedRowSetImpl();


try{
//modification des données
rowset.acceptChanges();
}catch(SyncProviderException spe){
SyncResolver resolver = spe.getSyncResolver();
int status = resolver.getStatus();
switch(status){
case SyncResovler.UPDATE_ROW_CONFLICT :
System.out.println("Conflit lors d'une mise à jour");
break;
switch(status){
case SyncResovler.DELETE_ROW_CONFLICT :
System.out.println("Conflit lors d'une suppression");
break;
switch(status){
case SyncResovler.INSERT_ROW_CONFLICT :
System.out.println("Conflit lors d'une insertion");
break;
}
//ensuite il faut déterminer quelle valeurs doivent être insérées
//pour cela l'implémentation de Sun offre quelques méthodes supplémentaires
}catch(SQLException sqle){
//etc..
}

Un exemple plus complet est donné dans la description de la classe SyncResolver. Par contre, la RI (intégrée dans le
JDK 5.0) ne semble pas fonctionner correctement. Le problème de synchronisation est bien détecté, mais la méthode
getConflictValue renvoi systématiquement null. Il est donc impossible de comparer la valeur du RowSet et celle de la
source de données. Par la suite, il est donc impossible de faire appel à la méthode setResolvedValue. Si quelqu'un à une
solution, elle est la bienvenue :)

lien : Comment détecter les modifications d'un RowSet déconnecté ?


lien : Comment annuler les modifications d'un RowSet déconnecté ?

Comment détecter les modifications d'un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
Pour détecter les modifications faites à un RowSet déconnecté, on peut utiliser un ensemble cinq de méthodes. Une
partie de celles-ci appartiennent à ResultSet alors que les autres appartiennent à CachedRowSet.

- 56 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

En utilisant des méthodes de ResultSet :

• rowDeleted() : Cette méthode indique si la ligne courante a été supprimée.


• rowInserted() : Cette méthode indique si la ligne courante a été insérée.
• rowUpdated() : Cette méthode indique si la ligne courante a été mise à jour.

Utilisez la méthode setShowDeleted pour permettre au curseur de passer sur les lignes qui ont été supprimées.

En utilisant des méthodes propres à CachedRowSet :

• columnUpdated(int index) : Cette méthode indique si la colonne d'index index à été mise à jour.
• columnUpdated(String nom) : Cette méthode indique si la colonne identifiée par nom à été mise à jour.

Ces méthodes peuvent lever une SQLException si l'index ou le nom ne sont pas valides, ou alors si il n'y a pas de ligne
courante.

Comment annuler les modifications d'un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
En plus des méthodes relatives aux transactions, plusieurs méthodes de CachedRowSet permettent d'annuler certaines
modifications. En plus de cela, on peut facilement avoir accès aux valeurs originales. Par valeurs originales on entends
les valeurs contenues dans le RowSet lors de son peuplement ou juste après le dernier appel à la méthode acceptChanges.

Comment annuler certaines modifications ?

• undoDelete() : Cette méthode permet d'annuler la suppression de la ligne courante


• undoInsert() : Cette méthode permet d'annuler l'insertion de la ligne courante
• undoUpdate() : Cette méthode permet d'annuler la modification de la ligne courante

On peux noter que ces trois méthodes peuvent être appelées à n'importe quel moment précédant un appel à
acceptChanges. Toutes trois lèvent une SQLException si la ligne pointée n'a pas été insérée, supprimée ou modifiée
(selon la méthode). Une exception est aussi levée si le curseur pointe sur une ligne comme beforeFirst, afterLast ou
insertRow.

Une dernière méthode permet l'annulation de toutes les modifications : c'est la méthode restoreOriginal. Cette méthode
annule toutes les insertions, suppressions et mises à jour et place le curseur avant la première ligne.

Comment retrouver les valeurs originales ?

• getOriginal() : Cette méthode retourne un ResultSet contenant les valeurs originales du RowSet. Ce
ResultSet réponds au standard des RowSet, c'est à dire ResultSet.TYPE_SCROLL_INSENSITIVE et
ResultSet.CONCUR_UPDATABLE . Le curseur est placé avant la première ligne.
• getOriginalRow() : Cette méthode retourne un ResultSet contenant les valeurs originales de la ligne courante.
Ce ResultSet réponds au standard des RowSet, c'est à dire ResultSet.TYPE_SCROLL_INSENSITIVE et

- 57 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

ResultSet.CONCUR_UPDATABLE . Le curseur est placé avant la première ligne. De plus une SQLException
est levée si il n'y a pas de ligne courante (ie. beforeFirst, afterLast ou insertRow).

lien : Comment détecter les modifications d'un RowSet déconnecté ?

Quel est le nombre de lignes d'un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
Contrairement à l'interface ResultSet, RowSet propose une méthode toute faite pour avoir accès aux nombres de tuples
qu'elle contient. Par exemple :

ResultSet resultat = ... ;


RowSet rowset = new CachedRowSetImpl();
rowset.populate(resultat);
int nombreDeLignes = rowset.size();
System.out.println("Nombre de lignes : "+nombreDeLignes);

Naturellement les méthodes proposées dans la réponse à la question Comment connaître le nombre de lignes/colonnes
d'un ResultSet ? restent valables. Mais plus très utiles ;-)

lien : Comment connaître le nombre de lignes/colonnes d'un ResultSet ?

Comment traiter de grandes quantités de données ?


Auteurs : Ioan Calapodescu ,
Si l'espace mémoire à allouer à une instance de RowSet déconnecté est limité, il est possible de traiter les données par
pages. Il suffit d'indiquer le nombre de lignes que l'on désire par page.

CachedRowSetImpl rowset = new CachedRowSetImpl();


//mise en place des propriétés du RowSet
rowset.setUrl("jdbc:mysql://localhost/MaBase");
rowset.setUsername("user");
rowset.setPassword("password");
rowset.setCommand("SELECT * FROM MaTable");
//on indique au RowSet de mettre 100 lignes par page
rowset.setPageSize(100);
//peuplement du RowSet
rowset.execute();
int index = 0;
while(rowset.nextPage()) {
//traitement de chaque page
System.out.println(" Page numéro "+(++index));
while(rowset.next()) {
//traitement des données de la page
}
}

- 58 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

La méthode setPageSize peut lever une SQLException si le paramètre est inférieur à zéro ou supérieur à la valeur
retournée par getMaxRows.

lien : Comment limiter le nombre de lignes des ResultSet renvoyées par l'instruction ?

Comment vider complètement un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
Pour faire cela, il faut utiliser la méthode release de CachedRowSet. Par exemple :

CachedRowSet rowset = new CachedRowSetImpl();


//mise en place des propriétés
rowset.execute();
//divers traitements
rowset.release();
//maintenant le RowSet est vide de toutes données

//par contre les propriétés (url, user, password, commande, ...) sont maintenues

La méthode release envoie un RowSetEvent de "type" rowSetChanged;

Il ne faut pas confondre cette méthode avec la méthode close. Cette dernière en plus de vider le RowSet le rends
disponible pour le GarbageCollector.

Quels types de copies peut on faire à partir d'un RowSet déconnecté ?


Auteurs : Ioan Calapodescu ,
L'interface CachedRowSet permet de faire quatre types de copies d'une instance particulière. Voici les méthodes
utilisées et leurs particularités :

• createCopy() : Crée une copie en profondeur de l'instance. Les modifications faites sur la copie ne sont pas
répercutées sur l'original. Les éventuels RowSetListener à l'écoute de l'original ne prennent pas en compte les
modifications de la copie. La copie aura par contre les mêmes caractéristiques que l'original en ce qui concerne
la possibilité d'être mis à jour, les mouvements possibles du curseur et les différents attributs (url, datasource,
etc .).
• createCopyNoConstraints() : Crée une copie en profondeur des données de l'instance. Les caractéristiques de la
copie sont les mêmes que pour la méthode createCopy.
• createShared() : Crée un "clone" de l'instance copiée. Toutes les modifications faites au clone sont répercutées
sur l'original, mais aussi sur tous les autres clones existants. De même, tout RowSetListener à l'écoute des
événements relatifs à l'original est enregistré auprès du (des) clone(s). Inversement tout nouveau listener mis à
l'écoute d'un clone l'est aussi sur l'original et les autres clones.
• createCopySchema() : Crée une copie vide de l'instance. C'est à dire une copie ne contenant aucune donnée.
Cette copie ne conserve que le schéma (la structure) du RowSet. Les modifications de la copie ne sont pas
répercutées sur l'original. Cette méthode peut facilement être utilisée pour stocker le schéma d'un WebRowSet
sous forme de fichier XML.

Toutes ces méthodes retournent des instances de CachedRowSet sauf createCopySchema qui renvoie simplement un
RowSet.

- 59 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Attention : ces copies peuvent lever des SQLException en fonction de l'implémentation. La javadoc est très évasive sur
le sujet. Par exemple, pour l'implémentation de Sun, une SQLException est levée pour toute copie si l'original à déjà
un RowSetListener (???).

- 60 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet > Les WebRowSet


Comment peupler ou sauvegarder un WebRowSet grâce aux fichiers XML ?
Auteurs : Ioan Calapodescu ,
Les WebRowSet peuvent écrire leurs données, méta-données et propriétés sous forme de fichiers XML. De même,
ils peuvent se peupler à partir d'un tel fichier. Les méthodes employées sont naturellement susceptibles de lever des
IOException, en plus des SQLException.

Ecriture

WebRowSet rowset = new WebRowSetImpl();


//mise en place des propriétés et peuplement
FileWriter writer = null;
try{
File destination = ... ;
writer = new FileWriter(destination);
rowset.writeXml(writer);
}catch(IOException ioe){
//etc.
}catch(SQLException sqle){
//etc.
}
finally{
if(writer!=null){try{writer.close();}catch(Exception e){}}
}

Lecture

WebRowSet rowset =new WebRowSetImpl();


FileReader reader = null;
try{
File source = ...;
rowset.readXml(source);
}catch(IOException ioe){
//etc.
}catch(SQLException sqle){
//etc.
}
finally{
if(reader!=null){try{reader.close();}catch(Exception e){}}
}

Naturellement, le fichier source doit être un fichier XML bien formé (Cf.Comment sont formés les fichiers XML des
WebRowSet ?).

lien : Comment peupler et envoyer un WebRowSet directement sur un flux ?


lien : Comment sont formés les fichiers XML des WebRowSet ?

Comment peupler et envoyer un WebRowSet directement sur un flux ?


Auteurs : Ioan Calapodescu ,
Un des avantages de WebRowSet est le fait que l'on n'est pas limité à l'écriture ou à la lecture de fichiers. WebRowSet
est capable d'écrire (ou de lire) sur n'importe quel type de flux. Cette capacité peut être particulièrement utile dans les
applications web. Voici l'exemple d'une servlet :

- 61 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Class.forName("com.mysql.jdbc.Driver");
//récupération des paramètres de la requête
String url = request.getParameter("url");
String username = request.getParameter("username");
String password = request.getParameter("password");
String command = request.getParameter("command");

//création et exécution du RowSet


WebRowSet rowset = new WebRowSetImpl();
rowset.setUrl(url);
rowset.setUsername(username);
rowset.setPassword(password);
rowset.setCommand(command);
rowset.execute();

//écriture de la réponse
response.setContentType("text/xml");
PrintWriter out = response.getWriter();
//rajout d'une éventuelle feuille de style
out.println("<?xml:stylesheet type=\"text/xsl\" href=\"simple.xsl\"?>");
//écriture du rowset
rowset.writeXml(out);

out.close();

Le contenu du WebRowSet est directement écrit sur le flux de la réponse. Vous pouvez même ajouter en début de page
un lien vers une feuille de style XSL pour mettre en forme les résultats.

lien : Comment sont formés les fichiers XML des WebRowSet ?

Comment sont formés les fichiers XML des WebRowSet ?


Auteurs : Ioan Calapodescu ,
Les fichiers XML correspondants aux WebRowSet ont pour racine un noeud WebRowSet. Celui-ci contient trois types
de noeuds, qui représentent respectivement les propriétés, les méta-données et les données du WebRowSet.

Structure générale :

<?xml version="1.0"?>
<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
<properties>
<!-- Contient les propriétés du WebRowSet -->
</properties>
<metadata>
<!-- Contient les méta-données du WebRowSet -->
</metadata>
<data>
<!-- Contient les données du WebRowSet -->
</data>
</webRowSet>

Structure des propriétés :

<properties>
<command>SELECT * FROM TestWebRowSet</command>
<concurrency>1008</concurrency>

- 62 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

<datasource><null/></datasource>
<escape-processing>true</escape-processing>
<fetch-direction>1000</fetch-direction>
<fetch-size>0</fetch-size>
<isolation-level>2</isolation-level>
<key-columns></key-columns>
<map></map>
<max-field-size>0</max-field-size>
<max-rows>0</max-rows>
<query-timeout>0</query-timeout>
<read-only>true</read-only>
<rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
<show-deleted>false</show-deleted>
<table-name>TestWebRowSet</table-name>
<url>jdbc:mysql://localhost/JDBC</url>
<sync-provider>
<sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
<sync-provider-vendor>Sun Microsystems Inc.</sync-provider-vendor>
<sync-provider-version>1.0</sync-provider-version>
<sync-provider-grade>2</sync-provider-grade>
<data-source-lock>1</data-source-lock>
</sync-provider>
</properties>

Cette partie contient les propriétés du WebRowSet, mais aussi des informations sur le SyncProvider (celui de Sun
dans l'exemple). On peut remarquer l'absence des propriétés username et password, qui naturellement doivent rester
secrètes.

Structure des méta-données :

<metadata>
<column-count>4</column-count>
<column-definition>
<!-- Informations sur la première colonne -->
</column-definition>
<column-definition>
<!-- Informations sur la deuxième colonne -->
</column-definition>
<!-- etc. -->
</metadata>

Les balises column-definition contiennent les informations relatives aux colonnes. Ces informations sont les mêmes que
celles accessibles grâce aux méta-données. Par exemple :

<column-index>2</column-index>
<auto-increment>false</auto-increment>
<case-sensitive>true</case-sensitive>
<currency>false</currency>
<nullable>1</nullable>
<signed>true</signed>
<searchable>true</searchable>
<column-display-size>7</column-display-size>
<column-label>unDecimal</column-label>
<column-name>unDecimal</column-name>
<schema-name></schema-name>
<column-precision>5</column-precision>
<column-scale>2</column-scale>
<table-name>TestWebRowSet</table-name>
<catalog-name></catalog-name>
<column-type>3</column-type>
<column-type-name>DECIMAL</column-type-name>

- 63 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Structure des données :

<currentRow>
<columnValue>1</columnValue>
<columnValue>0.01</columnValue>
<columnValue>chaine 0</columnValue>
<columnValue>1088200800000</columnValue>
</currentRow>
<currentRow>
<!-- données de la deuxième ligne -->
</currentRow>
<!-- etc. pour chaque ligne du WebRowSet -->

La balise data peut contenir trois autres types de balises, dont le contenu est identique à currentRow. Celles-ci définissent
les lignes ajoutées, modifiées ou supprimées.

<insertRow></insertRow>
<modifyRow>
<columnValue>valeurInitiale</columnValue>
<updateValue>valeurModifiee</updatevalue>
</modifyRow>
<deleteRow></deleteRow>

Les trois types de balise peuvent contenir des balises updateValue, qui représentent les valeurs modifiées.

lien : Comment peupler ou sauvegarder un WebRowSet grâce aux fichiers XML ?

- 64 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet > Les FilteredRowSet


Comment filtrer les données avec un FilteredRowSet ?
Auteurs : Ioan Calapodescu ,
Les FilteredRowSet permettent de filtrer facilement les données, sans passer par des commandes SQL complexes. Ce
genre de filtres peuvent être particulièrement utiles pour gérer l'affichage des données sans faire de multiples requêtes
vers la base. Pour filtrer les données il faut créer une classe implémentant Predicate. Dans celle-ci il suffira de définir
la méthode evaluate qui renvoie un boolean indiquant si une ligne donnée doit apparaître ou non. Par exemple :

public class MonPredicat implements Predicate{


public boolean evaluate(RowSet rowset){
try{
String nom = rowset.getString("nom");
//on ne garde ici que les personnes dont le nom commence par A
if(nom.startsWith("A")){return true;}
else{return false;}
}catch(SQLException sqle){
return false;
}
}
//etc...
}

Il ne reste plus qu'à indiquer au FilteredRowSet le prédicat qu'il doit utiliser.

FilteredRowSet rowset = new FilteredRowSetImpl();


//mise enplace des propriétés
rowset.setCommand("SELECT * FROM Annuaire");
rowset.setPredicate(new MonPredicat());
rowset.execute();
while(rowset.next()){
//seulement les lignes répondant favorablement au prédicat sont visibles
}

lien : Comment spécifier plusieurs filtres à un FilteredRowSet ?


lien : Comment spécifier plusieurs colonnes et ensembles de valeurs pour un filtre ?

Comment spécifier plusieurs colonnes et ensembles de valeurs pour un filtre ?


Auteurs : Ioan Calapodescu ,
On peut facilement spécifier plusieurs colonnes et ensembles de valeurs pour le filtrage de FilteredRowSet. Voici le
Predicate utilisé :

public class MonPredicat implements Predicate{


public Comparable[] valMin, valMax;
public int[] col;
public String[] nomCol;
public MonPredicat(Comparable[] valeursMinimales, Comparable[] valeursMaximales,
int[] colonnes, String[] nomsColonnes){
valMin = valeursMinimales;
valMax = valeursMaximales;
col = colonnes;
nomCol = nomsColonnes;
}
public boolean evaluate(Object value,int column) throws SQLException{
Comparable valeurMinimum = valMin[column];

- 65 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Comparable valeurMaximum = valMax[column];


return (valeurMinimum.compareTo(value)<=0)
&&((valeurMaximum.compareTo(value)>=0));
}
public boolean evaluate(Object value, String columnName) throws SQLException{
int column = Arrays.asList(nomCol).indexOf(columnName);
Comparable valeurMinimum = valMin[column];
Comparable valeurMaximum = valMax[column];
return (valeurMinimum.compareTo(value)<=0)
&&((valeurMaximum.compareTo(value)>=0));
}
public boolean evaluate(RowSet rowset){
try{
boolean ok = true;
int nombreColonnes = (col!=null)?col.length:nomCol.length;
for(int i=0;i<nombreColonnes && ok;i++){
if(col != null){
ok &amp;= evaluate(rowset.getObject(col[i]),col[i]);
}else{
ok &amp;= evaluate(rowset.getObject(nomCol[i]),nomCol[i]);
}
}
return ok;
}catch(SQLException sqle){
return false;
}
}
}

Ce prédicat prends en arguments 4 tableaux. Les deux premiers définissent les minimums et maximums. ce sont les
ensembles de valeurs acceptées par le filtre. Les deux derniers indiquent les colonnes sur lesquelles il faut appliquer le
filtre. Un seul de ces paramètres doit être spécifié. C'est à dire que l'on identifie les colonnes en fonction de leur indexe
ou en fonction de leur nom. Voici une exemple d'utilisation :

String url = "jdbc:mysql://localhost/test";


String user = "user";
String password = "pass";
String command = "SELECT * FROM Annuaire";
FilteredRowSet rowset = new FilteredRowSetImpl();
rowset.setUrl(url);
rowset.setUsername(user);
rowset.setPassword(password);
rowset.setCommand(command);
String[] nomsColonnes = new String[]{"id","nom","prenom"};
Comparable[] minimums = new Comparable[]{new Integer("200"),"a","b"};
Comparable[] maximums = new Comparable[]{new Integer("12360"),"f","c"};
Predicate predicat = new MonPredicat(minimums,maximums,null,nomsColonnes);
rowset.setFilter(predicat);
rowset.execute();
while(rowset.next()){
//dans ce cas seulement les tuples vérifiant les conditions suivantes sont affichés :
// - id (int) compris entre 200 et 12360
// - nom (String) : les noms compris entre a et f
// - prenom (String) : les prénoms compris entre b et c
}

lien : Comment filtrer les données avec un FilteredRowSet ?

- 66 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Comment spécifier plusieurs filtres à un FilteredRowSet ?

Comment spécifier plusieurs filtres à un FilteredRowSet ?


Auteurs : Ioan Calapodescu ,
Il n'existe pas de mécanisme disponible pour spécifier plusieurs filtres à un FilteredRowSet. Par contre, on peut
facilement créer un gestionnaire de filtres. Celui-ci nous permettrais d'utiliser plusieurs filtres simples et de combiner
leurs effets. L'avantage de cette manipulation est le fait de pouvoir facilement changer les "vues" de nos données. Voici
un exemple utilisant plusieurs filtres sous forme de clauses (ET logique) :

class GestionnairePredicats implements Predicate{


public Map<String,Predicate> filtres;
public GestionnairePredicats(){
filtres = new HashMap<String, Predicate>();
}
public Map<String, Predicate> getFiltres(){return filtres;}
public void setFiltres(Map<String, Predicate> lesFiltres){
filtres = lesFiltres;
}
public void addFiltre(String nom, Predicate filtre){
filtres.put(nom,filtre);
}
public void removeFiltre(String nom){
filtres.remove(nom);
}
public boolean evaluate(RowSet rowset){
boolean ok = true;
for(Predicate predicate : filtres.values()){
ok &amp;= predicate.evaluate(rowset);
}
return ok;
}
public boolean evaluate(Object value,int column) throws SQLException{
boolean ok = true;
for(Predicate predicate : filtres.values()){
ok &amp;= predicate.evaluate(value,column);
}
return ok;
}
public boolean evaluate(Object value, String columnName) throws SQLException{
boolean ok = true;
for(Predicate predicate : filtres.values()){
ok &amp;= predicate.evaluate(value,columnName);
}
return ok;
}
}

L'utilisation du gestionnaire est simple et ressemble à ceci :

String url = "jdbc:mysql://localhost/maBase";


String user = "user";
String password = "pass";
String command = "SELECT * FROM Annuaire";
FilteredRowSet rowset = new FilteredRowSetImpl();
rowset.setUrl(url);
rowset.setUsername(user);
rowset.setPassword(password);
rowset.setCommand(command);
GestionnairePredicats gestionnaire = new GestionnairePredicats();
rowset.setFilter(gestionnaire);

- 67 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

rowset.execute();
System.out.println("#################################################");
while(rowset.next()){
//par défaut toutes les lignes sont visibles
System.out.println(rowset.getObject("nom")+" , "+rowset.getObject("prenom"));
}
gestionnaire.addFiltre("filtre 1", new MonPredicat());
gestionnaire.addFiltre("filtre 2", new MonPredicat2());
rowset.beforeFirst();
System.out.println("#################################################");
while(rowset.next()){
//les deux filtres sont appliqués
System.out.println(rowset.getObject("nom")+" , "+rowset.getObject("prenom"));
}
gestionnaire.removeFiltre("filtre 1");
rowset.beforeFirst();
System.out.println("#################################################");
while(rowset.next()){
//seulement le second filtre est appliqué
System.out.println(rowset.getObject("nom")+" , "+rowset.getObject("prenom"));
}

On peut facilement améliorer cet exemple en définissant toutes les possibilités de la logique des prédicats.

lien : Comment filtrer les données avec un FilteredRowSet ?


lien : Comment spécifier plusieurs colonnes et ensembles de valeurs pour un filtre ?

- 68 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les RowSet > Les JoinRowSet


Comment faire un JOIN avec JoinRowSet ?
Auteurs : Ioan Calapodescu ,
L'interface JoinRowSet qui étend WebRowSet permet d'utiliser les JOIN SQL. Toute instance de Joinable peut faire
partie du JOIN, c'est à dire tout RowSet, qu'il soit connecté ou non. Il suffit juste de peupler le JoinRowSet de deux
Joinable (ou plus) et de lui 'indiquer quelles vont être les colonnes de comparaison. On peut noter que ces dernières
peuvent notamment avoir des noms et des types SQL différents (il suffit juste que les données soient comparables).
Voici un exemple :

/**Données nécessaires à la connexion*/


String url = "url";
String user = "user";
String password = "password";
/**Récupération des données dont on souhaite faire une jointure*/

// Création de la première partie du JOIN


CachedRowSet unJoinable = new CachedRowSetImpl();
unJoinable.setUrl(url);
unJoinable.setUsername(user);
unJoinable.setPassword(password);
unJoinable.setCommand("SELECT id, nom, prenom FROM Annuaire");
unJoinable.execute();
// Seconde partie du JOIN
CachedRowSet unAutreJoinable = new CachedRowSetImpl();
unAutreJoinable.setUrl(url);
unAutreJoinable.setUsername(user);
unAutreJoinable.setPassword(password);
unAutreJoinable.setCommand("SELECT id, nom, prenom FROM Annuaire2");
unAutreJoinable.execute();
/**Création de la jointure*/
JoinRowSet join = new JoinRowSetImpl();
//il suffit d'indiquer au JoinRowSet les colonnes de correspondance

//ici ce sera la première colonne, le champ id


join.addRowSet(unJoinable,1);
join.addRowSet(unAutreJoinable,1);
//lecture et traitement des données
while(join.next()){
for(int i=0; i<join.getMetaData().getColumnCount();i++){
System.out.print(join.getObject(i+1)+" ");
}
System.out.print("\n");
}

Il est même tout à fait envisageable de faire des jointures entre différentes bases de données, tournant sur différents
modèles de SGBDR.

lien : Quels types de JOIN peut-on faire avec JoinRowSet

Quels types de JOIN peut-on faire avec JoinRowSet


Auteurs : Ioan Calapodescu ,
L'interface JoinRowSet permet de faire 5 types de JOIN. Ceux-ci correspondent aux 5 variables publiques et statiques
de JoinRowSet.

• CROSS_JOIN
• FULL_JOIN

- 69 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• INNER_JOIN : c'est le type par défaut


• LEFT_OUTER_JOIN
• RIGHT_OUTER_JOIN

Pour spécifier le type de jointure, il faut utiliser la méthode setJoinType, en prenant soin de vérifier que l'implémentation
accepte le type de JOIN en question. Si le type de JOIN n'est pas supporté, une SQLException sera levée. Voici un
exemple :

JoinRowSet rowset = new JoinRowSetImpl();


if(rowset.supportsFullJoin()){
rowset.setJoinType(JoinRowSet.FULL_JOIN);
}

lien : Comment faire un JOIN avec JoinRowSet ?

- 70 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les transactions


Que sont les transactions ?
Auteurs : Ioan Calapodescu ,
Une transaction est un ensemble d'instructions devant s'exécuter d'un seul bloc. C'est à dire que les instructions sont
soit toutes exécutées, soit toutes annulées. Si une seule instruction du bloc échoue la transaction ne prends pas effet.

Par défaut, les Connection sont en mode auto-commit. C'est à dire que chaque instruction SQL est considérée comme
une transaction. Vous pouvez changer ce comportement en utilisant la méthode setAutoCommit(boolean).

Dans le cas ou l'auto-commit est desactivé, vous devrez appeller la méthode commit pour effectivement valider la
transaction. Voici un exemple :

Connection connection = null;


try{
connection = ...;
connection.setAutoCommit(false);

//traitement des différentes instructions composant la transaction

connection.commit();// c'est ici que l'on valide la transaction


connection.setAutoCommit(true);
}catch(SQLException sqle){
//vous pourrez annuler ici la transaction en cas d'exception
}finally{
try{connection.close();}catch(Exception e){}
}

Comment et quand annuler une transaction ?


Auteurs : Ioan Calapodescu ,
Pour annuler une transaction vous devez utiliser la méthode rollback. Cette méthode à pour effet d'annuler toutes les
modifications faites par la transaction courrante et de supprimmer les verrous en place.

Voici un exemple :

Connection connection = null;


try{
connection = ...;
connection.setAutoCommit(false);

//traitement des différentes instructions composant la transaction

if(jeVeuxValider){
connection.commit();// c'est ici que l'on valide la transaction
connection.setAutoCommit(true);
}else{
connection.rollback();
}
}catch(SQLException sqle){
try{connection.rollback();}catch(Exception e){}
}catch(Exception e){
try{connection.rollback();}catch(Exception e){}
}finally{
try{connection.close();}catch(Exception e){}

- 71 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Que sont les niveaux d'isolation des transactions ?


Auteurs : Ioan Calapodescu ,
JDBC prévois plusieurs niveaux d'isolation. Ces niveaux d'isolation déterminent la manière dont sont préservées les
données durant la transaction. C'est à dire que JDBC est capable de verrouiller (en lecture ou écriture) les données
tant que la transaction n'est pas validée.

Voici 4 des 5 niveaux d'isolation possibles, définis par des constantes de la classe Connection :

Niveau\Anomalie Lecture impropre Lecture non Lecture fantôme


répétable
TRANSACTION_READ_UNCOMMITTED
possible possible possible
TRANSACTION_READ_COMMITTED
impossible possible possible
TRANSACTION_REPEATABLE_READ
impossible impossible possible
TRANSACTION_SERIALIZABLE
impossible impossible impossible

Le dernier niveau est TRANSACTION_NONE et indique que les transactions ne sont pas supportées.

Voici la définition des anomalies :

• Lecture impropre (dirty read) : cette anomalie se produit lorsqu'une transaction lis des données qui sont en
train d'être modifiées par votre transaction (non encore validée).
• Lecture non répétable (non-repeatable read) : cette anomalie survient si une requête ne renvoie pas les mêmes
résultats lors d'exécutions successives. C'est le cas si les données que vous lisez sont modifiées par une autre
transaction (c'est un peu l'inverse de la lecture impropre).
• Lecture fantôme (phantom reads) : cette anomalie se produit si des exécutions successives d'une même requête
renvoient des données en plus ou en moins. Cela peut être le cas si une autre transaction est en train de
supprimer ou d'ajouter des données à la table.

Pour connaître le niveau d'isolation, vous pouvez utiliser la méthode getIsolationLevel de la classe Connection. De la
même manière vous pouvez changer ce niveau avec la méthode setIsolationLevel. Attention, toutes fois, car tous les
SGBDR ne supportent pas tous les types d'isolation.

Comment faire des mises à jour groupées, ou Batch Updates ?


Auteurs : Ioan Calapodescu ,
Depuis JDBC 2.0, la classe Statement (et ses dérivées) propose quelques méthodes pouvant faciliter les mises à jour
groupées.

Voici un exemple :

Connection connection = ... ;


Statement statement = connection.createStatement();
if(connection.getMetaData().supportsBatchUpdates()){
connection.setAutoCommit(false);
statement.clearBatch(); //on supprimme les anciens batch
statement.addBatch("INSERT ....");

- 72 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

statement.addBatch("UPDATE ...");
statement.addBatch("...");
int[] resultat = statement.executeBatch();
//voir les différents types de retour possibles
connection.commit();
connection.setAutoCommit(false);
}

Que renvoie l'exécution d'un batch ?


Auteurs : Ioan Calapodescu ,
L'exécution d'un batch retourne un tableau d'entiers. Ceux ci correspondent aux commandes insérées dans le batch
et ont trois valeurs possibles.

• Statement.EXECUTE_FAILED : L'exécution de la commande à échoué, mais aucune exception n'a été levée.
• Statement.SUCCESS_NO_INFO : L'exécution a réussi, mais il n'y a aucune information disponible sur le
nombre de lignes affectées par la mise à jour.
• Un entier supérieur ou égal à zéro : L'exécution a réussi. Cet entier représente le nombre de lignes affectées par
la mise à jour.

Comment gérer les exceptions lors d'un batch ?


Auteurs : Ioan Calapodescu ,
La méthod executeBatch est susceptible de le ver une BatchUpdateException si une des commandes lève
une SQLException ou retourne un ResultSet. BatchUpdateException, étendant SQLException, offre les mêmes
informations. On peut en plus obtenir un tablau d'entiers nous rensignant sur les résultats des commandes exécutées
avant celle levant l'exception.

Voici un exemple de traitement :

Connection connection = ... ;


Statement statement = ... ;
try{
connection.setAutoCommit(false);
// ajout des commandes au statement
int[] resultats = statement.executeBatch();
if(lExecutionEstSatisfaisante){
connection.commit();
}else{
connection.rollback();
}
}catch(BatchUpdateException bue){
int[] commandesExecutees = bue.getUpdateCounts();
System.out.println(commandesExecutees.length+
" commandes ont déjà été exécutées avant l'erreur ");
connection.rollback();
}catch(SQLException sqle){
try{connection.rollback();}catch(Exception e){}
}finally{
try{connection.setAutoCommit(true);}catch(Exception e){}
try{statement.close();}catch(Exception e){}

- 73 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Comment utiliser des points de sauvegarde dans les transactions ?


Auteurs : Ioan Calapodescu ,
La méthode rollback permet seulement d'annuler l'ensemble d'une transaction. Un mécanisme un peu plus intéressant
à fait son apparition avec JDBC 3.0 : l'utilisation de points de sauvegarde tout au long de la transaction. Ces points
de sauvegarde, représentés par l'interface Savepoint du package java.sql, permettent tout simplement de revenir en
arrière dans la transaction, mais de manière ciblée.

Voici un exemple :

Connection connection = ... ;


connection.setAutoCommit(false);

//une première instruction

Savepoint s1 = connection.setSavepoint("Premier point de sauvegarde");

//une deuxième instruction

Savepoint s2 = connection.setSavepoint(); // point de sauvegarde anonyme

//une troisième instruction

Savepoint s3 = connection.setSavepoint("Troisième point de sauvegarde");

connection.releaseSavepoint(s2); // on enlève le second savepoint


connection.rollback(s1); // toutes les modifications après s1 sont ignorées
connection.commit(); // finalement seulement la première instruction est validée

Comment savoir si le driver supporte les transactions ?


Auteurs : Ioan Calapodescu ,
Pour savoir sir le driver supporte les transactions vous pouvez utiliser les méthodes de DatabaseMetaData. Par exemple :

DatabaseMetaData metadata = ...;


if(metadata.supportsTransactions()){
System.out.println("Les transactions sont supportées");
if(metadata.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED){
//etc.
}
}else{
System.out.pritln("Ls transactions ne sont pas supportées");
}

- 74 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les types SQL et les types Java


Tableau de relations
Auteurs : Ioan Calapodescu ,
Voici un tableau de correspondances entre les types SQL définis dans java.sql.Types, les méthodes de ResultSet et les
types Java :

Type SQL Méthode ResultSet Type Java


ARRAY getArray java.sql.Array
BIGINT getLong long
BINARY getBytes byte[]
BIT getBoolean boolean
BLOB getBlob java.sql.Blob
CHAR getString java.lang.String
CLOB getClob java.sql.Clob
DATE getDate java.sql.Date
DECIMAL getBigDecimal java.math.BigDecimal
DINSTINCT getTypeDeBase typeDeBase
DOUBLE getDouble double
FLOAT getDouble double
INTEGER getInt int
JAVA_OBJECT (type)getObject type
LONGVARBINARY getBytes byte[]
LONGVARCHAR getString java.lang.String
NUMERIC getBigDecimal java.math.BigDecimal
OTHER getObject java.lang.Object
REAL getFloat float
REF getRef java.sql.Ref
SMALLINT getShort short
STRUCT (type)getObject type
TIME getTime java.sql.Time
TIMESTAMP getTimestamp java.sql.Timestamp
TINYINT getByte byte
VARBINARY getBytes byte[]
VARCHAR getString java.lang.String

On peut juste noter que les méthodes getObject et getString sont génériques et peuvent servir pour tous ces types.

Il ne faut pas oublier que ce tableau est simplifié, il existe d'autres types et correspondances. Pour plus d'informations,
suivez les liens ci-dessous.

lien : Comment connaître les types SQL supportés par la base de données ?
lien : Comment obtenir la liste des mots clefs SQL non standard d'un SGBDR ?

- 75 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

lien : Conversions by ResultSet.getXXX() Methods

Comment obtenir une instance de java.sql.Date, Time ou Timestamp ?


Auteurs : Ioan Calapodescu ,
Première méthode : passage par une java.util.Date Les classes Date, Time et Timestamp, du package java.sql, étendent
toutes java.util.Date. Pour obtenir une instance de celles-ci, le plus simple est de passer justement par une java.util.Date.
Par exemple :

java.util.Date date = new java.util.Date();


java.sql.Date dateSQL = new java.sql.Date(date.getTime());
Time time = new Time(date.getTime());
Timestamp time = new Timestamp(date.getTime());

Vous pouvez aussi utiliser la méthode setTime pour modifier une de ces instances.

Seconde méthode : passage par la syntaxe d'échappement Ces trois classes proposent une méthode statique
valueOf(String s) qui renvoye une instance correspondante. La chaîne de caractères passée en paramètre doit respecter
la syntaxe d'échappement. Par exemple :

Date date = Date.valueOf("2004-10-20");

Pour connaître les différents formats regardez Qu'est-ce que la syntaxe d'échappement ?.

lien : Qu'est-ce que la syntaxe d'échappement ?

A quoi correspond le type DISTINCT ?


Auteurs : Ioan Calapodescu ,
Le type DISTINCT est un UDT (User Defined Type) défini par la norme SQL 3. Ce type est basé sur un type déjà
existant. Par exemple :

CREATE TYPE TELEPHONE AS CHAR(10);

Dans cet exemple, on crée un nouveau type TELEPHONE. Celui-ci correspond à une chaîne de 10 caractères.

Attention : la syntaxe utilisée est celle de la norme SQL3, elle est peu utilisée en pratique.

La manipulation du type se fait grâce aux méthodes du type qu'il "étend". En imaginant un ResultSet contenant une
colonne Telephones contenant des données de type TELEPHONE :

ResultSet resultset = ...;


while(resultset.next()){
String telephone = resultset.getString("Telephones");
//...
}

- 76 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

De la même manière, on utiliserait setString pour le passage d'un argument de type TELEPHONE.

Quelles sont les relations entre tableau et java.sql.Array ?


Auteurs : Ioan Calapodescu ,
Un object de type java.sql.Array ne contient pas à proprement parler de données. C'est une sorte de pointeur vers les
données contenues dans le ARRAY SQL. Pour en récuperer les données vous devez faire comme ceci :

Statement statement = ... ;


String sql = "SELECT * FROM MaTable";
ResultSet resultset = statement.executeQuery(sql);
while(resultset.next()){
Array array = resultset.getArray("colonneArray");
//array est un simple "pointeur"
Object tableau = array.getArray();
//tableau est tableau Java
String[] donneesTableau = (String[])tableau;
//vous devez le caster dans le type de données contenues
for(int i=0; i<donneesTableau.length ; i++){
System.out.println(donneesTableau[i]);
}
}

Pour connaître le type SQL des données contenues dans le Array, vous pouvez utiliser les méthodes getBaseType()
et getBaseTypeName(). La première méthode est la plus intéressante, puisqu'elle renvoye le type correspondant dans
java.sql.Types.

Voici une autre méthode pour parcourir les données de l'Array, peut-être plus "élégante" et dans l'esprit JDBC car
elle utilise un ResultSet :

Statement statement = ... ;


String sql = "SELECT * FROM MaTable";
ResultSet resultset = statement.executeQuery(sql);
while(resultset.next()){
Array array = resultset.getArray("colonneArray");
//array est un simple "pointeur"
ResultSet tableau = array.getResultSet();
//tableau est un ResultSet contenant les données de l'Array
while(tableau.next()){
System.out.println(tableau.getString(1));
//le ResultSet n'a qu'une colonne
}
}

Quelle que soit la méthode que vous utilisez pour récuperer les données de l'Array, vous pouvez spécifier l'index et le
nombre d'éléments à récuperer. Par exemple :

Array array = resultset.getArray("colonneArray");


int index = 3;
int longueur = 4;

- 77 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

ResultSet tableau = array.getResultSet(index, longueur);

Qu'est ce qu'un LOB ?


Auteurs : Ioan Calapodescu ,
Un LOB ou Large OBject est une catégorie de types SQL 3. Il en existe deux : les BLOB et les CLOB. Ces types
permettent de stocker de grandes quantités de données dans une seule "celulle" d'une table.

BLOB

Un BLOB ou Binary Large OBject permet de stocker de grandes quantités de données sous forme binaire. On peut par
exemple insérer dans une table des fichiers (images, musique, etc.).

CLOB

Un CLOB ou Character Large OBject permet de stocker de grandes quantités de données sous forme de caractères.
On peut par exemple insérer dans une table des articles de journaux, des livres ou les pages d'un site internet.

JDBC a prévu pour la manipulation de ces deux types SQL les classes Clob et Blob du package java.sql. La plupart des
manipulations de ce objets se font directement en utilisant des flux. Pour plus d'informations, suivez les liens ci dessous.

lien : Comment insérer un BLOB dans une base de données ?

Comment insérer un BLOB dans une base de données ?


Auteurs : Ioan Calapodescu ,
Pour mettre en évidence l'insertion d'un BLOB dans une base de données, nous allons prendre pour exemple l'insertion
d'une image. Notre table ne contient que deux colonnes. La première sera le nom de l'image et la seconde l'image elle
même (le fichier).

public static void insererImage(String nom, String chemin) {


File file = new File(chemin);
try{
//lien vers la base de données
Connection connection = DriverManager.getConnection("url","user","password");

//lien vers notre fichier image


FileInputStream stream = new FileInputStream(file);

//préparation de l'instruction SQL


String sql = "INSERT INTO TableImages VALUES (?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);

//insertion de l'image
statement.setString(1, nom);
statement.setBinaryStream(2, stream, (int)file.length());
statement.executeUpdate();

}catch(Exception e){
//traitement des erreurs SQL, IO, etc .
}finally {
//fermeture de la connexion, du flux, etc.
}
}

- 78 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Pour un exemple plus complet regardez Utilisation de JDBC pour la gestion d'images en base de données par Ricky81 .

lien :
lien : Utilisation de JDBC pour la gestion d'images en base de données par Ricky81
lien : Comment lire un BLOB dans une base de données ?

Comment lire un BLOB dans une base de données ?


Auteurs : Ioan Calapodescu ,
La lecture d'un BLOB est relativement simple. Pour commencer, on doit récupérer une instance de Blob afin de
récupérer un flux de lecture sur celui-ci. Finalement, il ne reste qu'à lire ce flux.

Dans l'exemple ci-dessous, on lis une image dans une base de données afin de l'écrire sur le disque. L'utilisation de
ImageIO permet de facillement de récupérer le contenu du Blob sous forme de BufferedImage.

public static void extraireImage(String nom, String chemin) {


String destination = chemin + System.getProperty("file.separator")
+ nom + ".jpg";
File file = new File(destination);
try{
//lien vers la base de données
Connection connection = DriverManager.getConnection("url","user","password");

//préparation de l'instruction SQL


String sql = "SELECT * FROM TableImages WHERE nom = ? ";
PreparedStatement statement = connection.prepareStatement(sql);

//récupération de l'image (BLOB)


statement.setString(1, nom);
ResultSet resultat = statement.executeQuery();
resultat.first();
Blob blob = resultat.getBlob("images");

//lecture du blob et écriture sur le disque


BufferedImage image = ImageIO.read(blob.getBinaryStream());
FileOutputStream stream = new FileOutputStream(file);
ImageIO.write(image,"jpg",stream);

}catch(Exception e){
//traitement des erreurs SQL, IO, etc .
}finally {
//fermeture de la connexion, du flux, etc.
}
}

Pour une exemple plus complet regardez Utilisation de JDBC pour la gestion d'images en base de données par Ricky81.

lien :
lien : Utilisation de JDBC pour la gestion d'images en base de données par Ricky81
lien : Comment insérer un BLOB dans une base de données ?

Comment insérer un CLOB dans une base de données ?


Auteurs : Ioan Calapodescu ,
L'insertion d'un CLOB dans une base de données se fait grâce à un flux de caractères. Voici un exemple qui lis le contenu
d'un fichier et le stocke sous forme de CLOB :

- 79 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

public static void insererTexte(String nomFichier){


File file = new File(nomFichier);
BufferedReader fileReader = null;
String texte = "";
StringReader stringReader = null;
Connection connection = null;
PreparedStatement statement = null;
try{
//lectute du contenu du fichier à inserer
fileReader = new BufferedReader(new FileReader(file));
String ligne = null;
while((ligne = fileReader.readLine()) != null){
texte += ligne+"\n";
}

//préparation de la connexion
connection = DriverManager.getConnection("url","login","pass");
String sql = "INSERT INTO ClobTable (nom,article) VALUES (?, ?)";
statement = connection.prepareStatement(sql);

//on met en place les paramètres du statement


statement.setString(1,file.getName());
stringReader = new StringReader(texte);
statement.setCharacterStream(2,stringReader,texte.length());

//exécution de l'instruction
statement.executeUpdate();

}catch(Exception e){
e.printStackTrace();
}finally{
try{fileReader.close();}catch(Exception e){}
try{stringReader.close();}catch(Exception e){}
try{statement.close();}catch(Exception e){}
try{connection.close();}catch(Exception e){}
}
}

lien : Comment lire un CLOB dans une base de données ?


lien : Comment faire une recherche dans un CLOB ?

Comment lire un CLOB dans une base de données ?


Auteurs : Ioan Calapodescu ,
L'interface Clob du package java.sql permet de récupérer un flux de caractères sous forme de Reader. Voici un exemple
qui récupère le texte contenu dans un CLOB et l'affiche sur la sortie standard :

public static void lectureTexte(String nomArticle){


BufferedReader clobReader = null;
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultset = null;
try{
//préparation de la connexion
connection = DriverManager.getConnection("url","login","pass");
String sql = "SELECT article FROM ClobTable WHERE nom = ?";
statement = connection.prepareStatement(sql);

//on met en place les paramètres du statement


statement.setString(1,nomArticle);

//exécution de la requête

- 80 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

resultset = statement.executeQuery();

//récupération et lecture du clob


if(resultset.next()){
Clob clob = resultset.getClob("article");
clobReader = new BufferedReader(clob.getCharacterStream());
String ligne = null;
while((ligne = clobReader.readLine()) != null){
System.out.println(ligne);
}
}else{
System.out.println("Article "+nomArticle+" introuvable");
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{clobReader.close();}catch(Exception e){}
try{resultset.close();}catch(Exception e){}
try{statement.close();}catch(Exception e){}
try{connection.close();}catch(Exception e){}
}
}

lien : Comment insérer un CLOB dans une base de données ?


lien : Comment faire une recherche dans un CLOB ?

Comment faire une recherche dans un CLOB ?


Auteurs : Ioan Calapodescu ,
L'interface Clob du package java.sql permet de facilement faire une recherche dans le contenu d'un CLOB. Voici une
exemple permettant de rechercher toutes les occurences d'un mot dans une table contenant des "articles" :

public static void rechercherTexte(String recherche){


Connection connection = null;
Statement statement = null;
ResultSet resultset = null;
try{
//préparation de la connexion
connection = DriverManager.getConnection("url","login","pass");
statement = connection.createStatement();

//exécution de la requête
String sql = "SELECT * FROM ClobTable";
resultset = statement.executeQuery(sql);

//recherche dans les différents clob


while(resultset.next()){
String nomArticle = resultset.getString("nom");
System.out.println("Recherche de "+recherche+" dans "+nomArticle);
Clob clob = resultset.getClob("article");
long indexe = 1;//Attention : le premier caractère est d'indexe 1
while((indexe = clob.position(recherche,indexe)) != -1){
System.out.println(" mot trouvé en "+indexe);
indexe++;
//ne pas oublier d'incrementer l'indexe
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{resultset.close();}catch(Exception e){}
try{statement.close();}catch(Exception e){}
try{connection.close();}catch(Exception e){}

- 81 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

}
}

lien : Comment insérer un CLOB dans une base de données ?


lien : Comment lire un CLOB dans une base de données ?

Comment faire la relation entre un UDT et un Object Java ?


Auteurs : Ioan Calapodescu ,
Pour faire la relation entre un UDT (User Defined Type) et un objet Java vous devrez tout d'abord créer une classe
implémentant SQLData. Voici un exemple :

UDT PERSONNE :

CREATE TYPE PERSONNE


(
NOM VARCHAR(40),
PRENOM VARCHAR(40),
AGE INTEGER
);

Objet Java Personne :

public class Personne implements SQLData{


private String nom;
private String prenom;
private int age;
private String typeSql;

//Définition des constructeurs

//Définition des getters/setters

//Implémentation de SQLData
public String getSQLTypeName() {
return typeSql;
}
public void readSQL(SQLInput stream, String type)
throws SQLException {
typeSql = type;
nom = stream.readString();
prenom = stream.readString();
age = stream.readInt();
}

public void writeSQL(SQLOutput stream)


throws SQLException {
stream.writeString(nom);
stream.writeString(prenom);
stream.writeInt(age);
}
}

Utilisation :

Connection connection = ...;

// mise en place du mapping

- 82 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Map map = con.getTypeMap();


map.put("Schema.PERSONNE", Class.forName("Personne");

// utilisation
Statement statement = ...;
String sql = "SELECT Personnes FROM Annuaire";
ResultSet resultset = statement.executeQuery(sql);
while(resultset.next()){
Personne personne = (Personne)resultset.getObject(1);
System.out.println("Nom = "+personne.getNom());
System.out.println("Prenom = "+personne.getPrenom());
System.out.println("Age = "+personne.getAge());
}

- 83 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les méta-données - MetaData

- 84 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les méta-données - MetaData > Généralités et informations sur le SGBD
Que sont les méta-données ?
Auteurs : Ioan Calapodescu ,
Les méta-donné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ême. Les méta-donné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 le 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.

Comment connaître le nom et la version du SGBD utilisé ?


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

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().

Quels sont les catalogues du SGBD utilisé ?


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

Connection connection = DriverManager.getConnection(url,user,password);


//on récupère les métadonnées à partir de la Connection
DatabaseMetaData dmd = connection.getMetaData();
//récupération des informations
String catalogTerm = dmd.getCatalogTerm();
ResultSet resultat = dmd.getCatalogs();
//affichage des informations

- 85 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

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);
}

Quelles sont les normes SQL supportées par le SGBD ?


Auteurs : Ioan Calapodescu ,
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 les plus indépendants possibles, par rapport aux SGBD ou aux implémentations des Drivers. Voici quelques
exemples :

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 intermediaire) = "
+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 ;-).

Comment connaître les types SQL supportés par la base de données ?


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

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);
}
}

- 86 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

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 case
• 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 peux être utilisé comme valeur monétaire.
• AUTO_INCREMENT boolean = indique si le type peux ê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 peux pas être NULL
• typeNullable - peux ê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écuperer que le nom des types, on peut
faire comme ceci :

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

- 87 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

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).

Comment obtenir la liste des mots clefs SQL non standard d'un SGBDR ?
Auteurs : Ioan Calapodescu ,
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 entends les mots clefs n'appartenant pas à la norme SQL92.

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 :

AUTO_INCREMENT
BINARY
BLOB
ENUM
INFILE
LOAD
MEDIUMINT
OPTION
OUTFILE
REPLACE
SET
TEXT
UNSIGNED
ZEROFILL

Comment obtenir la liste des fonctions (numériques, système, etc.) ?


Auteurs : Ioan Calapodescu ,
Ces différentes listes sont accessibles depuis la classe DatabaseMetaData.

- 88 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• 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 :

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;
}

Connection connection = DriverManager.getConnection(url,user,password);


ArrayList liste = getAllFunctions(connection);
for(Iterator it = liste.iterator();it.hasNext();){
System.out.println(it.next());
}

Comment avoir la liste de toutes les procédures stockées dans une base de données ?
Auteurs : Ioan Calapodescu ,
L'accès à cette information se fait grâce à DatabaseMetaData et grâce à la méthode getProcedures. Par exemple :

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);

- 89 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Dans cet exemple, on passe % comme paramètre de recherche sur le nom, ce qui a pour effet de rechercher toutes les
procédures.

Comment connaître les caractéristiques d'une procédure stockée ?


Auteurs : Ioan Calapodescu ,
La méthode getProcedureColumns de DatabaseMetaData permet d'avoir accès aux informations relatives a une ou
plusieurs procédures stockées. Cette méthode renvoie un ResultSet donc chaque ligne décris un paramètre ou une
colonne de la procédure. Par exemple :

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;

- 90 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

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.

Quels sont les "maximums" supportés par le SGBD ?


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

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'à foullier
dans la javadoc ;-)

Quelles sont les noms et versions du driver utilisé ?


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

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);

- 91 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les méta-données - MetaData > Informations sur les tables
Comment récupérer les noms des tables d'une base de données ?
Auteurs : Ioan Calapodescu ,
L'interface DatabaseMetaData permet d'acceder à de nombreuses informations sur les tables d'une base de données,
notamment grâce à la méthode getTables.

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
ResultSet tables = dmd.getTables(connection.getCatalog(),null,"%",null);
//affichage des informations
while(tables.next()){
System.out.println("###################################");
for(int i=0; i<tables.getMetaData().getColumnCount();i++){
String nomColonne = tables.getMetaData().getColumnName(i+1);
Object valeurColonne = tables.getObject(i+1);
System.out.println(nomColonne+" = "+valeurColonne);
}
}

Ce premier exemple permet d'obtenir toutes les tables et informations disponibles. On peut remarquer la présence du
symbole % pour l'attribut définissant le nom de la table. Celui-ci permet d'indiquer que l'on recherche n'importe quel
nom.

On peux naturellement cibler sa recherche en spécifiant une colonne précise du ResultSet. Voici la liste des principales
colonnes du ResultSet renvoyé par getTables.

• TABLE_CAT String = Le nom du catalogue auquel appartient la table.


• TABLE_SCHEM String = Le schema de la table.
• TABLE_NAME String = Le nom de la table.
• TABLE_TYPE String = Le type de la table. Ce type peux être : "TABLE", "VIEW", "SYSTEM TABLE",
"GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
• REMARKS String = Commentaires sur la table.

Remarque : il en existe d'autres, mais elles ne sont pas toujours présentes. Cela dépend de l'implémentation et du SGBD.

On peut par exemple facilement créer une méthode nous indiquant la présence d'un table dans une base.

public static boolean existe(Connection connection, String nomTable) throws SQLException{


boolean existe;
DatabaseMetaData dmd = connection.getMetaData();
ResultSet tables = dmd.getTables(connection.getCatalog(),null,nomTable,null);
existe = tables.next();
tables.close();
return existe;
}

L'utilisation pourrais ressembler à ceci :

Connection connection = DriverManager.getConnection(url,user,password);


System.out.println("Existance d'une table dans la base de données : "+
existe(connection,"%"));

- 92 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

System.out.println("Existance de la table MaTable : "+


existe(connection,"MaTable"));
System.out.println("Existance d'une table dont le nom commence par 'a' : "+
existe(connection,"a%"));
System.out.println("Existance d'une table dont le nom fait 5 caractères et fini par e : "+
existe(connection,"____e"));

Comment récupérer les clefs primaires d'une table ?


Auteurs : Ioan Calapodescu ,
L'interface DatabaseMetaData permet de retrouver les clefs primaires d'une table. Par exemple :

Connection connection = ...;


DatabaseMetaData metadata = connection.getMetaData();
String nomTable = "MaTable";
ResultSet clefs = metadata.getPrimaryKeys(connection.getCatalog(),null,nomTable);
while(clefs.next()){
String nomColonne = clefs.getString("COLUMN_NAME");
System.out.println("La colonne "+nomColonne+"est une clef primaire de "+nomTable);
}

Comment récupérer des informations sur les colonnes d'une table ?


Auteurs : Ioan Calapodescu ,
DatabaseMetaData permet de retrouver des informations sur les colonnes d'une table grâce à la méthode getColumns.
Voici un exemple :

Connection connection = DriverManager.getConnection(url,user,password);

//on récupère les métadonnées à partir de la Connection


DatabaseMetaData dmd = connection.getMetaData();

//récupération des informations


String nomDeLaTable = "le nom de la table qui nous intéresse";
ResultSet resultat = dmd.getColumns(connection.getCatalog(),null,nomDeLaTable, "%");

//affichage des informations


ResultSetMetaData rsmd = resultat.getMetaData();
while(resultat.next()){
for(int i=0; i<rsmd.getColumnCount(); i++){
String col = rsmd.getColumnName(i+1);
Object val = resultat.getObject(i+1);
System.out.println(col+" = "+val);
}
}

- 93 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Vous trouverez plus d'informations, sur les paramètres de cette méthode et sur la structure du ResultSet retourné, dans
la Javadoc.

Comment connaître les droits de l'utilisateur sur une table ?


Auteurs : Ioan Calapodescu ,
Cette information est accessible grâce à DatabaseMetaData et à la méthode getTablePrivileges. Cette méthode retourne
un ResultSet dont chaque ligne correspond aux droits d'une table répondant au pattern passé pour le nom.

public static void getDroits(Connection connection, String nomTable) throws SQLException{


DatabaseMetaData dmd = connection.getMetaData();
System.out.println("Droits de "+dmd.getUserName()+" pour la(les) table(s) "+nomTable);
ResultSet droits = dmd.getTablePrivileges(null,null,nomTable);
while(droits.next()){
//de qui viennent les doits
String grantor = droits.getString("GRANTOR");
//a qui appartiennent les droits
String grantee = droits.getString("GRANTEE");
//quels sont ces droits (select, insert, etc.)
String privilege = droits.getString("PRIVILEGE");
//possibilité de donner ces droits à un tiers
String grantable = droits.getString("IS_GRANTABLE");
System.out.println("grantor = "+grantor);
System.out.println("grantee = "+grantee);
System.out.println("privilege = "+privilege);
System.out.println("grantable = "+grantable);
}
droits.close();
}

De la même manière, on peut utiliser la méthode getColumnPrivileges pour avoir des informations sur les droits sur
une colonne ou un ensemble de colonnes. Les colonnes du ResultSet sont identiques.

Attention, ces deux méthodes sont susceptibles de lever une SQLEception, si l'utilisateur n'a pas certains droits. Par
exemple pour MySQL, il faut avoir les droits de lecture sur la base de données mysql. Tout dépends de l'implémentation.

Comment récupérer des informations sur les index d'une table ?


Auteurs : Ioan Calapodescu ,
DatabaseMetaData permet de récupérer des informations sur les indexes d'une table donnée (ou de plusieurs), grâce à la
méthode getIndexInfo. Voici un exemple permettant d'afficher sur la sortie standard toutes les informations disponibles
pour les indexes d'une table nommée "MaTable".

Connection connection = DriverManager.getConnection(url,user,password);

//on récupère les métadonnées à partir de la Connection


DatabaseMetaData dmd = connection.getMetaData();

//récupération des informations


ResultSet resultat = dmd.getIndexInfo(connection.getCatalog(),null,"MaTable", false, false);

//affichage des informations


ResultSetMetaData rsmd = resultat.getMetaData();
while(resultat.next()){

- 94 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

for(int i=0; i<rsmd.getColumnCount(); i++){


String col = rsmd.getColumnName(i+1);
Object val = resultat.getObject(i+1);
System.out.println(col+" = "+val);
}
}

Explication :
Les deux premiers paramètres correspondent au catalogue et au schéma. Ensuite, on indique le nom de la table (ici
"MaTable"). Pour ce paramètre, on peut, comme toujours avec les méta-données, utiliser les caractères % et _, pour
sélectionner plusieurs tables. Vous trouverez plus d'informations sur ces paramètres et sur la structure du ResultSet
récupéré dans la Javadoc.

- 95 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Les méta-données - MetaData > Informations sur les ResultSet
Comment connaître le nombre de lignes/colonnes d'un ResultSet ?
Auteurs : Ioan Calapodescu ,
Pour connaître le nombre de colonnes d'un ResultSet, il suffit d'utiliser ResultSetMetaData. Par exemple :

String sql = "SELECT * FROM MATABLE";


Statement statement = connection.createStatement();
ResultSet resultat = statement.executeQuery(sql);
ResultSetMetaData metadata = resultat.getMetaData();
int nombreColonnes = metadata.getColumnCount();
System.out.println("Ce ResultSet contient "+nombreColonnes+" colonnes.");

Par contre, il n'existe pas de méthode toute faite pour récupérer le nombre de lignes d'un ResultSet. Cette fonctionnalité
à été retirée des premières spécifications, car les implementations étaient trop gourmandes en ressources. Il existe
plusieurs possibilités pour connaître cette valeur.

Si le ResultSet est de type TYPE_SCROLL_XXX

String sql = "SELECT * FROM MATABLE";


Statement statement = connection.createStatement();
ResultSet resultat = statement.executeQuery(sql);
//on place le curseur sur le dernier tuple
resultat.last();
//on récupère le numéro de la ligne
int nombreLignes = resultat.getRow();
//on repace le curseur avant la première ligne
resultat.beforeFirst();
System.out.println("Ce ResultSet contient "+nombreLignes+" lignes.");

Si le ResultSet est de type TYPE_FORWARD_ONLY, la seule possibilité est d'utiliser une autre requête faisant un
COUNT.

Une dernière possibilité est d'utiliser les RowSet qui proposent une méthode toute faite pour récupérer cette
information.

Comment récupérer les noms des colonnes d'un ResultSet ?


Auteurs : Ioan Calapodescu ,
L'interface ResultSetMetaData permet de récupérer les noms des colonnes d'un ResultSet. Deux méthodes sont à notre
disposition :

• getColumnName(int column) : String : Cette méthode renvoye le nom de la colonne dont l'index est column.
• getColumnLabel(int column) : String : Cette méthode renvoye le nom, suggéré pour l'affichage, de la colonne
dont l'index est column

Attention : en pratique les implementations renvoient souvent les mêmes chaînes de caractères pour les deux méthodes.

Voici une méthode pour récupérer les noms des colonnes d'un ResultSet sous forme de tableau de String :

- 96 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

public String[] getNomsColonnes(ResultSet resultat) throws SQLException{


ResultSetMetaData metadata = resultat.getMetaData();
String[] noms = new String[metadata.getColumnCount()];
for(int i = 0; i < noms.length; i++){
String nomColonne = metadata.getColumnName(i+1);
noms[i] = nomColonne;
}
return noms;
}

Pour récupérer les noms de toutes les colonnes d'une table, on pourrais utiliser cette méthode comme ceci :

Connection connection = DriverManager.getConnection(url,user,password);


String sql = "SELECT * FROM MaTable";
Statement statement = connection.createStatement();
ResultSet resultat = statement.executeQuery(sql);
String[] noms = getNomsColonnes(resultat);
for(int i = 0; i < noms.length; i++){
System.out.println(noms[i]);
}

Comment récupérer les types SQL et Java des colonnes d'un ResultSet ?
Auteurs : Ioan Calapodescu ,
Trois méthodes de ResultSetMetaData peuvent nous renseigner sur le type SQL et sur la classe java correspondante
d'une colonne donnée.

• getColumnClassName(int index) : renvoie une chaîne de caractères correspondant au nom complet de la classe
java de la colonne ciblée par index.
• getColumnType(int index) : renvoie un entier correspondant au type SQL de la colonne ciblée par index. Cet
entier est un de ceux définis dans java.sql.Types.
• getColumnTypeName(int index) : renvoie une chaîne de caractères correspondant au type SQL de la colonne
ciblée par index. Cette chaîne est le nom de la variable renvoyée par getColumnType dans java.sql.Types.

Par exemple :

Connection connection = DriverManager.getConnection(url,user,password);


String sql = "SELECT * FROM MaTable";
Statement statement = connection.createStatement();
ResultSet resultat = statement.executeQuery(sql);
ResultSetMetaData metadata = resultat.getMetaData();
for(int i = 0; i< metadata.getColumnCount(); i++){
int index = i+1;
int typeSQL = metadata.getColumnType(index);
String nomTypeSQL = metadata.getColumnTypeName(index);
String typeJava = metadata.getColumnClassName(index);
System.out.println("INFORMATIONS SUR LA COLONNE D'INDEXE "+index);
System.out.println("Type SQL dans java.sql.Types : "+typeSQL);
System.out.println("Nom du type SQL : "+nomTypeSQL);
System.out.println("Classe java correspondante : "+typeJava);

- 97 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Quelles informations peut-on avoir sur les colonnes de type numérique d'un ResultSet ?
Auteurs : Ioan Calapodescu ,
ResultSetMetaData possède plusieurs méthodes spécifiques aux colonnes contenant des données numériques. Par
exemple :

ResultSet resultat = ...;


ResultSetMetaData = resultat.getMetaData();
//index de la colonne à étudier
int index = ...;
//contient des valeurs signées
boolean valeursSignees = metadata.isSigned(index);
//est auto-incrémentée
boolean auto = metadata.isAutoIncrement(index);
//précision
int precision = metadata.getPrecision(index);
//nombre de chiffres après la virgule
int scale = metadata.getScale(index);
//est une valeur monétaire
boolean monetaire = metadata.isCurrency(index);

A quelle table correspond la colonne x de mon ResultSet ?


Auteurs : Ioan Calapodescu ,
Le nom de la table à laquelle appartient une colonne donnée est accessible avec la méthode getTableName de
ResultSetMetaData. Voici une méthode permettant de récupérer la liste de toutes les tables d'ou proviennent les données
d'un ResultSet.

public List getTables(ResultSet resultat) throws SQLException{


List liste = new ArayList();
ResultSetMetaData metadata = resultat.getMetaData();
for(int i = 0; i<metadata.getColumnCount(); i++){
String nomTable = metadata.getTableName(i);
if(!liste.contains(nomTable)&&!nomTable.equals("")){
liste.add(nomTable);
}
}
return liste;
}

La méthode getTableName renvoie une chaîne vide si la colonne n'est pas remplie à partir d'une table. C'est la seconde
vérification que nous faisons dans le if.

Quels types de ResultSet supporte le Driver ?


Auteurs : Ioan Calapodescu ,
Pour avoir accès à cette information, vous pouvez utiliser DatabaseMetaData. Par exemple :

- 98 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

DatabaseMetadata metadata = ...;


boolean b1 = metadata.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
boolean b2 = metadata.supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);

- 99 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > La gestion des erreurs


Comment gérer une SQLException ?
Auteurs : Ioan Calapodescu ,
La plupart des méthodes de l'API JDBC sont susceptibles de lever une SQLException. En plus de la méthode
getMessage, disponible pour tous les types d'exception, cette classe fournis trois autres méthodes importantes :

• getErrorCode() : retourne un entier représentant le code de l'erreur. Ce code est spécifique a chaque
distributeur (Driver).
• getSQLState() : retourne une chaîne de caractères représentant le "SQLState" de l'erreur. Cet état est défini
par une des deux conventions : XOPEN ou SQL99.
• getNextException() : retourne une possible SQLException liée à l'instance.

Voici un exemple :

try{
//code susceptible de lever une SQLException
}catch(SQLException sqle){
System.out.println("Exception SQL : ");
while (sqle != null) {
String message = sqle.getMessage();
String sqlState = sqle.getSQLState();
int errorCode = sqle.getErrorCode();
System.out.println("Message = "+message);
System.out.println("SQLState = "+sqlState);
System.out.println("ErrorCode = "+errorCode);
sqle.printStackTrace();
sqle = sqle.getNextException();
}
}
finally{
//etc.
}

On peut aussi spécifier la prochaine SQLException grâce à la méthode setNextException. Par exemple :

public void maMethode() throws SQLException{


try{
//du code pouvant lever une SQLException
}catch(SQLException sqle){
SQLException monException = new SQLException("monMessage");
monException.setNextException(sqle);
throw monException;
}
}

Que sont les SQLWarning ?


Auteurs : Ioan Calapodescu ,
La classe SQLWarning étends SQLException. Elle représente une erreur durant la connection à la base, durant
l'exécution d'une instruction ou durant la récupération de données contenues dans un ResultSet. Au contraire de
SQLException, cette erreur n'est pas "fatale" au programme : l'exception n'est pas levée, mais simplement stockée.
Par conséquent, il faut récupérer soi même les warnings. La méthode getWarnings est disponible pour Connection,
Statement et ResultSet. En voici les particularités :

- 100 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

• Connection : La méthode getWarnings retourne le premier warning relatif à cette Connection. Si la connexion
est fermée une SQLException est levée.
• Statement : La méthode getWarnings retourne le premier warning relatif à ce Statement. Si un ResultSet est
en train d'être lu, les warnings relatifs à celui-ci sont ajoutés à la liste. Les warnings sont remis à zéro à chaque
exécution du Statement. Si le Statement est fermé une SQLException est levée.
• ResultSet : La méthode getWarnings retourne le premier warning relatif à ce ResultSet. La liste des warnings
est remise à zéro à chaque lecture de ligne. Si le ResultSet est fermé une SQLException est levée.

Voici un exemple :

try{
Class.forName("nom.du.Driver").newInstance();
String url = "jdbc:...";
String user = "user";
String password = "mdp";
Connection connection = DriverManager.getConnection(url,user,password);
//étude des warnings relatifs à la connexion
SQLWarning warning = connection.getWarnings();
printWarning(warning);
//exécution d'un statement
Statement statement = connection.createStatement();
ResultSet resultat = statement.executeQuery("une requête");
//étude des warnings relatifs à l'exécution de l'instruction
warning = statement.getWarnings();
printWarning(warning);
while(resultat.next()){
//étude des warnings relatifs au ResultSet
warning = resultat.getWarnings();
printWarning(warning);
//traitement des infos
}
} catch(SQLException sqle){
//traitement des exceptions
}

Et voici le corps de la méthode printWarning qui permet juste d'afficher sur la sortie standard les informations sur le
SQLWarning passé en paramètre.

public void printWarning(SQLWarning warning) throws SQLException{


if(warning==null){
System.out.println("Bonne nouvelle, il n'y a pas de warning.");
return;
}
while(warning!=null){
String message = warning.getMessage();
String sqlState = warning.getSQLState();
int errorCode = warning.getErrorCode();
System.out.println("Message = "+message);
System.out.println("SQLState = "+sqlState);
System.out.println("ErrorCode = "+errorCode);
warning.printStackTrace();
warning = warning.getNextWarning();
}
}

- 101 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Remarque : on peut explicitement nettoyer les warnings (pour les trois classes) grâce à la méthode clearWarnings.

Les DataTruncation, warning ou exception ?


Auteurs : Ioan Calapodescu ,
DataTruncation étends SQLWarning. Mais à la différence de sa classe mère, DataTruncation est susceptible d'être
levée (comme toute exception).

• Warning : pour une lecture de données


• Exception : pour une écriture de données

On peux facilement identifier une DataTruncation par son SQLState qui est 01004. Par contre, sachant qu'aucune
méthode ne renvoie une instance de DataTruncation, il sera nécessaire de faire un cast. Par exemple :

} catch(SQLException sqle){
System.out.println("Exception SQL : ");
while (sqle != null) {
String message = sqle.getMessage();
String sqlState = sqle.getSQLState();
int errorCode = sqle.getErrorCode();
System.out.println("Message = "+message);
System.out.println("SQLState = "+sqlState);
System.out.println("ErrorCode = "+errorCode);
if(sqle instanceof DataTruncation){
//on fait ici la vérification sur la classe et non sur le SQLState
//car la spécification n'est pas toujours suivie à la lettre
DataTruncation dt = (DataTruncation)sqle;
System.out.println("Taille qui aurait du être transférée (bytes) : "+dt.getDataSize());
System.out.println("Taille effectivement transférée (bytes) : "+dt.getTransferSize());
//etc.
}
sqle = sqle.getNextException();
}
}

Comment connaître la signification d'un SQLState ou d'une ErrorCode ?


Auteurs : Ioan Calapodescu ,
Il n'existe pas de méthode toute faite dans l'API JDBC pour connaître la définition exacte d'un SQLState ou d'une
ErrorCode. La seule information intéressante que l'on peut obtenir est la convention du SQLState. Pour cela il faut
utiliser DatabaseMetaData :

Connection connection = ...;


DatabaseMetaData dmd = connection.getMetaData();
int type = dmd.getSQLStateType();
String sType = "";
if(type == DatabaseMetaData.sqlStateSQL99){
sType = "SQL99";
}
if(type == DatabaseMetaData.sqlStateXOpen ){
sType = " XOPEN";
}
System.out.println("Les SQLState suivent la norme "+sType);

- 102 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Pour le reste, il faut se renseigner auprès du distributeur pour connaître la signification exacte d'un ErrorCode. Pour
SQLState, il faut faire les vérifications en fonction de la norme utilisée.

- 103 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Mapping O/R, frameworks de persistance et autres API

- 104 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Mapping O/R, frameworks de persistance et autres API > Généralités
Existe-t-il des API de plus "haut niveau" que JDBC ?
Auteurs : Ioan Calapodescu ,
JDBC reste une API de "bas niveau". Elle est parfois difficile à prendre en main. Il existe de nombreuses API construites
sur JDBC, qui sont plus faciles d'utilisation. En voici quelques unes :

• DbUtils : API du projet Jakarta Commons créée pour faciliter le travail avec JDBC.
• Commons SQL : API du projet Jakarta Commons permettant de travailler avec des bases de données et de
créer des DDL.
• Les frameworks de persistance ou de mapping O/R : pour plus d'informations regardez : Que sont le mapping
Objet/Relationnel et les frameworks de persistance ?.

lien : Que sont le mapping Objet/Relationnel et les frameworks de persistance ?

Que sont le mapping Objet/Relationnel et les frameworks de persistance ?


Auteurs : Ioan Calapodescu ,
Le mapping O/R (objet/relationnel) est un mécanisme permettant de lier des objets (au sens Java et POO) au contenu
d'un SGBDR. Il existe de nombreux outils, API et spécifications permettant de faire ceci. En voici quelques uns :

• Hibernate : http://www.hibernate.org/
• JPOX : http://www.jpox.org/index.jsp
• iBatis : http://ibatis.com/common/sqlmaps.html
• OJB : http://db.apache.org/ojb/

Pour plus d'informations sur la spécification JDO, regardez : http://java.sun.com/products/jdo/index.jsp et http://


jdocentral.com/.

lien : La F.A.Q Hibernate

Ou trouver plus d'informations sur ces outils/API ?


Auteurs :
Vous pouvez trouver plus d'informations sur ces API dans les parties JDBC, J2EE ou Eclipse de la page cours de la
rubrique Java. Par exemple :

• Simplifiez vous JDBC avec Jakarta Commons DbUtils


• Utilisation de JDO sur une base de donnée relationnelle
• JSF et Hibernate
• Débuter avec Hibernate sous Eclipse

lien : La F.A.Q Hibernate


lien : La F.A.Q Eclipse

- 105 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Mapping O/R, frameworks de persistance et autres API > JDO
Qu'est ce que JDO ?
Auteurs : Ioan Calapodescu ,
JDO (Java Data Objects) est une spécification définissant une API pour la persistance. Vous pouvez trouver une
définition plus détaillée dans le tutoriel sur l'utilisation de JDO sur une base de donnée relationnelle de Benoit
Moussaud : JDO : Définition.

Ou trouver des implémentations de JDO ?


Auteurs : Ioan Calapodescu ,
JDO est une simple spécification. Il existe donc plusieurs implémentations. La RI (ou Reference Implementation) est
JPOX (http://www.jpox.org/).
Vous pouvez trouver une liste des mplémentations sur JDOCentral (site de la communauté JDO).
- Commercial Implementations
- Non-Commercial Implementations

Ou trouver plus d'informations sur JDO ?


Auteurs : Ioan Calapodescu ,
Voici plusieurs liens utiles sur JDO :
- Tutoriel de Benoit Moussaud sur l'utilisation de JDO sur une base de donnée relationnelle.
- JDO : site de Sun.
- JDO : site d'Apache. Sun Microsystems a decidé de donner Java Data Objects (JDO) à la communauté open source.
Les spécifications vont être désormais développées par le projet Apache JDO.
- JDOCentral : site de a communauté JDO.

- 106 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Mapping O/R, frameworks de persistance et autres API > DbUtils
Le QueryRunner peut-il utiliser un objet DataSource ?
Auteurs : Christophe Jollivet ,
Le QueryRunner peut utiliser un objet DataSource pour interroger la base de données. Le DataSource peut être donné
en paramètre au constructeur du QueryRunner ou préciser par la méthode

setDataSource(DataSource ds)

Peut-on utiliser des PreparedStatement avec le QueryRunner ?


Auteurs : Christophe Jollivet ,
L'usage de PreparedStatement se fait simplement. Lorsque l'on appelle la méthode query, les paramètres sont :

• la connexion sous la forme d'un objet Connection. Ce paramètre est optionnel si l'on a paramètré un
DataSource
• la requête SQL sous la forme d'un String avec des points d'interrogation à la place des paramètres
• un tableau d'objet correspondant aux paramètres (String, Integer,#) dans l'ordre de substitution.
• le ResultSetHandler qui parsera le ResultSet et renverra la réponse.

Quel est le format du fichier de requêtes utilisé par le QueryLoader ?


Auteurs : Christophe Jollivet ,
Ce fichier est au format properties c'est a dire :

String1 = String2

avec String1 une référence qu'on peut appeler et String2 la requête que l'on veut charger.

Pourquoi le QueryLoader ne peut charger mon fichier de requêtes ?


Auteurs : Christophe Jollivet ,
Le fichier de requêtes doit être dans le package et son chemin doit être relatif. Ainsi si le fichier queries.properties qui
se trouve dans le package "mon.package.jdbc", le chemin est "/mon/package/jdbc/queries.properties".

Quels sont les types de ResultSetHandler ?


Auteurs : Christophe Jollivet ,
ResultSetHandler est une interface ne présentant qu'une méthode :

Object handle(java.sql.ResultSet rs)

- 107 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Des implémentation d'origine existent permettant de retourner un objet List, un ArrayList, un Bean, un Map, ou un
List des deux précédents types.

Quel type d'objet peut renvoyer un ResultSetHandler ?


Auteurs : Christophe Jollivet ,
L'interface défini la méthode

Object handle(java.sql.ResultSet rs)

donc votre implémentation de cette interface peut renvoyer n'importe quel type d'objet. C'est à vous de caster l'objet
renvoyé dans le type adapté. Seuls les types primitifs ne peuvent être retournés, il faut utiliser les classes permettant
de les encapsuler (Integer, Boolean, Float,#)

Pourquoi certains champs renvoyés par le Bean(List)Handler


sont null alors que la base contient des données ?
Auteurs : Christophe Jollivet ,
Les types et les noms de la base de données doivent correspondre aux types et noms des attributs du bean. Si ce n'est
pas le cas, vous devez écrire votre propre implémentation de l'interface ResulSetHandler.

- 108 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Sommaire > Divers


Comment obtenir des informations sur les paramètres d'un PreparedStatement ?
Auteurs : Ioan Calapodescu ,
L'interface ParameterMetaData permet d'obtenir des informations sur les paramètres d'un PreparedStatement. Par
exemple :

String sql = "...";


PreparedStatement statement = connection.prepareStatement(sql);
ParameterMetaData metadata = statement.getParameterMetaData();
for(int i=0; i<metadata.getParameterCount(); i++){
String classe = metadata.getParameterClassName(i);
int mode = metadata.getParameterMode(i);
String sMode = "";
switch(mode){
case ParameterMetaData.parameterModeIn:
sMode = "IN";
break;
case ParameterMetaData.parameterModeOut:
sMode = "OUT";
break;
case ParameterMetaData.parameterModeInOut:
sMode = "INOUT";
break;
case ParameterMetaData.parameterModeUnknown:
sMode = "inconnu";
break;
default : sMode = "bug!!!";break;
}
int type = metadata.getParameterType(i);
String sType = metadata.getParameterTypeName(i);
int precision = metadata.getPrecision(i);
int scale = metadata.getScale(i);
int nullable = metadata.isNullable(i);
String sNullable = "";
switch(nullable){
case ParameterMetaData.parameterNoNulls:
sNullable = "ne peux pas être NULL";
break;
case ParameterMetaData.parameterNullable:
sNullable = "peux être NULL";
break;
case ParameterMetaData.parameterNullableUnknown:
sNullable = "inconnu";
break;
default : sNullable = "bug!!!";break;
}
boolean sign = metadata.isSigned(i);
System.out.println("INFORMATIONS SUR LE PARAMETRE D'INDEX "+i);
System.out.println("Classe java = "+classe);
System.out.println("Mode = "+mode+" : "+sMode);
System.out.println("Type dans java.sql.Types = "+type);
System.out.println("Nom du type = "+sType);
System.out.println("Précision = "+precision);
System.out.println("Scale = "+scale);
System.out.println("Nullable = "+nullable+" : "+sNullable);
System.out.println("Signé = "+sign);
}

- 109 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

Attention, il ne faut pas confondre getParameterMetaData et getMetaData. La seconde méthode permet de récupérer
les méta-données des ResultSet produits par le PreparedStatement. Ces méta-données sont récupérées sous forme de
ResultSetMetaData.

Comment connaître les requêtes envoyées à la base de données ?


Auteurs : Ioan Calapodescu ,
Il n'existe pas de mécanisme standard à JDBC pour connaître quelles sont les requêtes envoyées au SGBD. Certains
drivers redéfinissent les méthodes toString() (pour Statement, PreparedStatement ou CallableStatement). Mais, il est
difficile de faire une application "portable" dans ces conditions.

Heureusement, il existe une API pouvant aider à surveiller les requêtes envoyées au SGBD : P6SPY.
Cette API définit en fait un "driver" qui va englober le driver réel. Pour plus d'informations, regardez la documentation
de P6SPY : http://www.p6spy.com/documentation/

Existe-t-il une manière générique pour créer une BD avec JDBC ?


Auteurs : Ioan Calapodescu ,
Malheureusement, non, il n'existe pas de manière générique pour créer une base de données avec JDBC. En fait JDBC
est obligé d'avoir une base de données à laquelle se connecter pour pouvoir travailler.

Il existe tout de même une possibilité : il faut utiliser une Connection factice qui servira de pont entre vous et le SGBD.
A partir de cette Connection vous pourrez exécuter une instruction spécifique au SGBD pour créer une autre base de
données.

Voici une méthode qui permet de créer un base de données MySql et d'obtenir une Connection à celle-ci :

public static Connection createMysqlDatabase(Connection factice, String user,


String pass, String nomBase)
throws SQLException{
Connection connection = null;
Statement statement = null;
try{
statement = factice.createStatement();
statement.execute("CREATE DATABASE "+nomBase);
String url = factice.getMetaData().getURL();
url = url.substring(0,url.lastIndexOf("/"));
url += "/"+nomBase;
connection = DriverManager.getConnection(url,user,pass);
}catch(SQLException e){
SQLException sqle = new SQLException("Création de la base impossible");
sqle.setNextException(e);
throw sqle;
}finally{
try{statement.close();}catch(Exception e){}
}
return connection;
}

Vous pouvez utiliser cette méthode comme ceci :

Class.forName("com.mysql.jdbc.Driver");

- 110 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/
La FAQ JDBC

String url = "jdbc:mysql://host/baseLien";


String user = "user";
String pass = "password";
// on commence par se connecter à la base factice
Connection factice = DriverManager.getConnection(url,user,pass);
// on crée la base et on récupère une Connection
Connection connection = createMysqlDatabase(factice,user,pass,"NouvelleBase");
// on peut finalement fermer notre Connection factice qui ne nous sers plus à rien
factice.close();

Comment se connecter à une base de donnée Access sans créer un lien ODBC ?
Auteurs : duj ,
Il suffit d'utiliser l'URL suivante :

jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb);DBQ=labase.mdb;

Bien entendu, à la place de "labase", mettez le chemin complet de votre base (par exemple c:/temp/labase.mdb).

Voici un exemple complet de code pour obtenir une Connection :

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url= "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/temp/thebase.mdb";
String user = "user";
String pass = "pass";
Connection connection = DriverManager.getConnection(url,user,pass);

- 111 -
Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources
constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 - 2009 Developpez LLC. Tout 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'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://java.developpez.com/faq/jdbc/