Connexion d’un programme Java à une base de données via JDB
Il est courant aujourd’hui d’avoir à développer des applications bases de données relationnelles. En java c’est l’API et les drivers JDBC qui fournissent les fonctionnalités permettant de se connecter et d’exécuter des requêtes SQL sur une base de données. L’intérêt de cette API est de fournir une méthodes d’accès standard quelque soit le SGBD utilisé.
Pour qu’une application Java puisse accéder à une base de données, que se soit pour consulter ou modifier des données, vous devrez réaliser un certains nombre d’actions dans cet ordre :
Vous devrez récupérer le pilote JDBC de la base de données que vous désirez utiliser. En principe, c’est le constructeur du SGBD qui fournie le driver. Un moyen simple est de le récupérer sur Internet à partir du site http://developers.sun.com/product/jdbc/drivers. Un driver JDBC se présente sous la forme d’une archive .jar et est donc multi-plateforme (si type 4).
Une fois l’archive récupérée, vous devrez l’installer dans un dossier de votre disque dur. Vous aurez le choix entre :
Dans ce dernier cas vous devrez spécifier à votre programme comment retrouver le fichier bibliothèque pour utiliser le pilote :
L’exemple suivant montre un extrait d’un fichier .bashrc d’un système LINUX avec les différentes variables d’environnements définies pour une base Derby.
Pour charger le pilote en mémoire, vous avez 2 possibilités. Soit votre programme charge manuellement le pilote soit il ajoute le pilote à la liste des propriétés systèmes sous le nom jdbc.driver.
a) Chargement manuel du pilote.
Le chargement s’effectue en utilisant la méthode forName() de la classe Class en passant une chaine contenant le nom de la classe.
Le code suivant montre comment charger le pilote d’une base de données Derby pour le mode embarqué.
Vous devrez consulter la documentation de chaque pilote pour connaître les chaines de caractères à utiliser. Le tableau suivant donne quelques exemples de chaines de définition de pilote.
Classe de pilote | Description |
---|---|
org.apache.derby.jdbc.EmbeddedDriver | Pilote Derby en mode embarqué |
org.apache.derby.jdbc.ClientDriver | Pilote Derby en mode client/serveur. |
com.mysql.jdbc.Driver | Pilote MySql |
org.firebirdsql.jdbc.FBDriver | Pilote Firebird |
sun.jdbc.odbc.JdbcOdbcDriver | Driver pnt JDBC/ODBC fourni par sun. Il est déconseillé d’utiliser ce type de driver en production. |
com.ibm.db2.jdbc.app.DB2Driver | Pilote DB2 d’IBM |
b)Chargement du pilote par ajout d’une propriété système.
Vous avez 2 manières d’ajouter le pilote.
Vous pouvez l’ajouter en utilisant l’option -D en argument de ligne de commande lors du lancement du programme. L’exemple suivant vous montre comment lancer une application utilisant un pilote Derby :
L’autre méthode étant de l’ajouter par le programme. Exemple :
Une fois le pilote chargé en mémoire, nous devons nous connecter à la base de données. Pour cela nous devrons utiliser un objet de type Connection que nous pourrons récupérer en utilisant une des méthodes de la classe DriverManager suivante :
ou :
La première méthode permet de définir les paramètres de connexions dans une chaîne unique dont la syntaxe est la suivante :
"jdbc:sous-protocole:[//hote:][port]/nomBaseDeDonnées"
Cette chaine est construite comme une url , le sous-protocole correspondant au SGBD utilisé. Vous devrez consulter la documentation de chaque driver pour connaître l’url exacte en fonction du SGBD.
Cela donnera pour se connecter à une base de donnée Derby se trouvant sur une machine UNIX et nommé base_exemple :
Le tableau suivant donne quelques exemples d’url de connexions :
url | Description |
---|---|
jdbc:firebirdsql ://160.133.103:3052/d :\d :\databases\exemples_base.fdb | Connexion à une base de données firebird avec spécification de l’adresse IP et n° de port. La base de données se trouvant sur un serveur Windows |
jdbc:derby ://localhost:1527/exemple_base ;create=true | Connexion à une base derby.Un paramètre propre à cette base spécifie qu’une base sera créée si pas trouvée. |
jdbc:mysql ://localhost/exemple_base | Connexion à une base MySql en localhost |
5.1 Présentation du programme
Comme exemple, nous allons réaliser un programme permettant de se connecter à une petite base de données (une seule table) puis, nous afficherons les erreurs en cas d’echec.
Dans cet exemple nous utiliserons la version de Derby installée avec le JDK 6 sachant que seul les chemins des répertoires seront à adapter si vous utilisez une autre version de Derby. Nous utiliserons également le driver pour le mode embarqué de la base pour éviter d’avoir à configurer un serveur de bases de données. Pour bien comprendre ce que nous faisons, un simple éditeur de texte sera utilisé pour saisir le premier programme.
Le tableau suivant donne les paramètres de connexions :
Type de la base de données | Base de données Derby en mode embarqué. |
Classe du pilote | org.apache.derby.jdbc.EmbeddedDriver |
URL | jdbc:derby :///home/christophe/databases/derby_dbs/mediatheque |
Nom d’utilisateur : | non utilisé |
Mot de passe : | non utilisé |
Nous n’utiliserons pas de spécifions de login utilisateur ni mot de passe pour ces tests, derby désactivant par défaut l’authentification.
5.2 Écriture du programme et exécution
Créez un répertoire puis créez dans celui-ci un fichier TestConnexion.java. Puis saisissez le code suivant :
Le code chargeant le driver et réalisant la connexion à la base de données se trouve dans la méthode getConnection().
Sauvegardez, compilez et exécutez le programme.
java TestConnexion
Connexion en cours...
5.3. Programme bases de données en utilisant un IDE .
Dans le cadre d’un développement réel il est indispensable d’utiliser un IDE . Nous allons voir que cela nous facilite grandement les choses mêmes pour de petits programmes.
Ecriture de l’exemple du programme de connexion dans Eclipse.
Lancez Eclipse et créez un nouveau projet java. Comme nous allons utiliser le pilote de base de données contenu dans l’archive derby.jar, nous devons le spécifier dans le projet. Pour cela, affichez la fenêtre des propriétés du projet (racourcis clavier : alt+entrée), sélectionnez l’option JavaBuild Path et l’onglet Libraries. Cliquez sur le bouton Add External JARs... puis sélectionnez le fichier derby.jar.
Créer un package testjdbc par exemple, créez une classe TestConnexion en cochant la création automatique de la méthode main() puis, retapez le code de l’exemple précédent. Enregistrez et exécutez. Normalement, vous devriez voir s’afficher le texte suivant dans la vue Console :
Connexion en cours...
Fin de connexion
Récupérer un objet Statement
Maintenant que nous sommes connecté à la base de données nous devons récupérer un objet Statement qui nous permettra d’exécuter toutes requêtes SQL sur la base de données. A partir d’un objet Connection vous pourrez utiliser la méthode suivante :
Statement createStatement()
Exemple :
Lancer l’exécution de requêtes
Cette classe dispose de plusieurs méthodes permettant d’exécuter des requêtes SQL . Vous utiliserez plutôt l’une ou l’autre selon le type de requête. Voici la liste de ces différentes méthodes :
ResultSet executeQuery( String sql )
Exécute une requête de sélection (SELECT) et renvoi une liste d’enregistrements dans un objet ResultSet.
int executeUpdate( String sql )
Exécute une requête de mise à jour (INSERT, UPDATE ou DELETE) ou une commande SQL de type DLL comme par exemple CREATE TABLE. Cette méthode renvoi le nombre d’enregistrements modifiés lorsqu’il s’agit d’une requête de mise à jour sinon -1.
boolean execute( String sql )
Permet d’exécuter une requête SQL quelconque. Retourne la valeur true si l’exécution de la requête renvoi un ensemble résultat sinon false.
Si la méthode execute renvoi true, vous devrez pouvoir exploiter les résultats avec les 2 méthodes suivante :
int getUpdateCount()
qui renvoi le nombre d’enregistrements disponibles ou -1 si la méthode execute ne renvoie pas d’ensembles résultats et :
ResultSet getResultSet()
qui permet de récupérer l’ensemble résultat.
Récupérer les données de la requête
Un objet ResultSet contient l’ensemble de données résultant d’une requête sélection.
Cette classe dispose des méthodes suivante pour vous permettre d’exploiter les données retournées
boolean next()
Avance d’une ligne dans le ResultSet et renvoi true tant que vous n’êtes pas sur la dernière ligne. Vous devrez appeler une première fois cette méthode pour pouvoir récupérer la première ligne.
void close()
Ferme l’ensemble résultat.
Pour balayer l’ensemble des lignes vous pourrez créer une boucle de ce type :
Pour récupérer les informations, vous disposez d’une série de méthodes get.. auxquelles vous passerez en paramètre soit le nom du champ soit son numéro d’ordre (commence par 1). Il existe une version de ces méthodes pour chaque type de données courantes d’une base de données permettant de retourner la valeur dans un type Java compatible.
Les noms de ces méthodes auront la forme suivante :
typeJava getTypeJava( int columnNumber )
typeJava getTypeJava( String columnName )
Le tableau suivant présente la correspondance entre quelques types SQL et Java avec le nom de la méthode get correspondantes
Type java | Méthode d’accès | Type SQL à récupérer |
---|---|---|
boolean | getBooelan(...) | BIT |
byte | getByte(...) | TINYINT |
short | getShort | SMALLINT |
int | getInt | INTEGER |
long | getLong | BIGINT |
float | getFloat | REAL |
double | getDouble | FLOAT, DOUBLE |
BigDecimal | getBigDecimal | DECIMAL, NUMERIC |
String | getString | CHAR, VARCHAR |
java.sql.Date | getDate | DATE |
Time | getTime | TIME |
Timestamp | getTimestamp | TIMESTAMP |
... |
Exemple de programme affichant le résultat d’une requête
Le programme reprend l’exemple précédent mais saisie dans Eclipse et en ajoutant l’affichage du contenu de la table. La méthode de connexion a également été modifiée pour lire les paramètres à partir d’un fichier properties.
Le fichier database.properties a la structure suivante :
Les requêtes préparés sont des requêtes pré compilées paramétrables. Il suffira de mettre le caractère « ? » dans la requêtes aux emplacements paramétrables. Pour cela, il faut récupérer un objet PreparedStatement avec la méthode suivante :
PreparedStatement ps = connection.prepareStatement( String commandeSql )
comme dans l’exemple suivant :
Un objet PreparedStatement dispose de méthodes setXXX permettant d’initialiser les paramètres de la requête en passant d’abord son numéro. Le premier « ? » Correspondant au paramètre n°1.
Depuis la version 2 de JDBC, il est possible d’avoir des résultats de requêtes défilant. C’est à dire que vous pourrez non seulement avancer mais aussi reculer dans la source de données. Cela peut être utile si vous désirez relier votre ResultSet à un JTable dans le but de visualiser le résultat dans une interface graphique. Il pourra être également intéressant de pouvoir modifier une ligne du ResultSet et que cela entraine la mise à jour de la base de données ou au contraire, si les données de la base évoluent que le ResultSet reflète ces changements pour mettre à jour l’affichage. Pour préciser ses options nous utiliserons l’une des méthodes suivantes :
Statement st = connection.createStatement( type, concurrency );
ou pour une requête préparée :
PreparedStatement st =
connection.prepareStatement( requête, type, concurrency );
Grace aux 2 paramètres types et concurrency vous pourrez spécifier le comportement du ResultSet. Les tableaux suivant résument les différentes options possibles.
Les valeurs pour type :
Constante | Description |
---|---|
TYPE_FORWARD_ONLY | Pas de possibilité de défilement |
TYPE_SCROLL_INSENSITIVE | On peut faire défiler l’ensemble de résultat mais ne se met pas à jour automatiqument en cas de changement dans la base. |
TYPE_SCROLL_SENSITIVE | On peut faire défiler l’ensemble résultat et ce dernier est mis à jour en cas de changement dans la base. |
Les valeurs pour concurrency :
Constante | Description |
---|---|
ONCUR_READ_ONLY | L’ensemble résultat ne peut être utilisé pour mettre à jour la base de données. |
CONCUR_UPDATABLE | L’ensemble résultat peut être utilisé pour mettre à jour la base de données. |
Par exemple, si vous désirez faire défiler un ensemble résultat en lecture seule vous pourriez utiliser le code suivant :
Vous pouvez maintenant vous déplacer dans votre ensemble de données en utilisant les méthodes suivantes :
Pour aller à l’enregistrement suivant :
if ( resultset.next() ) …
Pour aller à l’enregistrement précédent :
if ( resultset.previous() ) …
Déplacement relatif vers l’avant ou l’arrière :
resultset.relative( n );
Déplacement absolut :
resultset.absolute( n );
Les précédentes méthodes renvoient true si après la tentative de déplacement elles se trouvent sur un enregistrement. Si ce n’est pas possible, le curseur se positionne avant le premier enregistrement ou après le dernier et renvoi false.
Il est également possible de récupérer le n° de ligne actuelle à avec la méthode suivante :
int n = resultset.getRow();
La première ligne a la valeur 1. Si la méthode renvoi 0 c’est que le curseur ne se trouve pas sur une ligne.
Un certains nombre de méthodes existent pour se déplacer directement sur le premier ou dernier enregistrement et pour tester si c’est le cas :
first(), last(), beforeFirst(), afterLast(), isFirst(), isLast()...
Pour utiliser un ensemble de données actualisables, vous devrez utiliser d’abord les méthodes suivantes pour mettre à jour les champs :
resultset.updateString( champ, valeur );
resultset.updateDouble( champ, valeur );
…
Vous trouverez une méthode updateXXX pour tous les types de dnnées. Comme pour les méthodes get et set, vous pouvez spécifier le champ par son nom ou son nuyméro.
Ensuite vous devrez valider (enregistrement dans la base) la mise à jour de la ligne en cours avec la méthode :
resultset.updateRow();
ou annuler cette mise à jour avec :
resultset.cancelRowUpdate();
Exemple de code de mise à jour :
Statement st = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATE );
…
ResultSet rs = st.executeQuery( requeteSql );
…
rs.updateString( "CMP_NOM", "BACH" );
rs.updateRow();
Pour passer en mode ajout d’un enregistrement vous devrez utiliser la méthode suivante :
resultset.moveToInsertRow();
Initialisez les champs avec des méthodes updateXxxx puis validez avec la méthode :
resultset.insertRow();
Vous pourrez repositionner le curseur sur la ligne courante avec :
resultset.moveToCurrentRow();
Pour supprimer la ligne courante de la base utilisez :
resultset.deleteRow();
Remarques et limites des requêtes lives
Les ensembles de résultats vivants demandent à ce que la connexion soit permanente. Vous ne devrez donc pas utiliser cette méthode pour une application Web. Il existe également une interface nommée RowSet qui permet d’avoir un ensemble de lignes défilantes sans pour autant être connecté à une source de données.
Il y a plusieurs niveaux de drivers qui vont supporter ou pas l’ensemble des possibilités du ResultSet selon que vous aurez des drivers de type JDBC1, JDBC2 ou JDBC3.
Indépendamment du niveau de driver, il est également possible que vous ne puissiez pas mettre à jour des données à partir un ensemble de résultats s’il s’agit d’une requête complexe ou comportant des jointures.
Cet article ne vous a présenté qu’une partie des possibilités de JDBC. D’autre part, on peut constater que cette approche n’est pas très objet, qu’il faut gérer beaucoup d’exceptions qui nous oblige à taper beaucoup de codes. Pour des projets d’importance, vous ne devrez pas utiliser directement l’API JDBC. Vous devrez utiliser une couche supplémentaire au dessus de JDBC, que l’on nomme mapping objet /relationnel qui vous permet au niveau de l’application, d’utiliser des objets pour manipuler des données sauvegardées dans une base de données relationnelle.
Crée par: chris
Créé le: 8 mai 2010
Modifié le: 31 octobre 2019
Nombre de visites: 1190
Popularité: 12 %
Popularité absolue: 1
2003-2024 LePpf
Plan du site
| Se connecter |
RSS 2.0 |
Sur YouTube
Visiteurs connectés : 1
Nombre moyen de visites quotidiennes sur le site: 204