[go: up one dir, main page]

100% ont trouvé ce document utile (1 vote)
314 vues47 pages

Gérer une Base de Données avec JDBC

Ce document décrit comment se connecter et interagir avec une base de données en Java à l'aide de JDBC. Il explique les étapes pour charger le pilote JDBC, se connecter à une base de données et exécuter des requêtes SQL.

Transféré par

losus007
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
100% ont trouvé ce document utile (1 vote)
314 vues47 pages

Gérer une Base de Données avec JDBC

Ce document décrit comment se connecter et interagir avec une base de données en Java à l'aide de JDBC. Il explique les étapes pour charger le pilote JDBC, se connecter à une base de données et exécuter des requêtes SQL.

Transféré par

losus007
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 47

Java : gérer une base de données avec JDBC

Achref El Mouelhi

Docteur de l’université d’Aix-Marseille


Chercheur en programmation par contrainte (IA)
Ingénieur en génie logiciel

elmouelhi.achref@gmail.com

H & H: Research and Training 1 / 41


Plan

1 Introduction

2 Utilisation

3 Transactions

4 Restructuration du code
Classes connexion et dao
DataSource et fichier de propriétés

H & H: Research and Training 2 / 41


Introduction

JDBC

Pour se connecter à une base de données


Il nous faut un JDBC (qui varie selon le SGBD utilisé)
JDBC : Java DataBase Connectivity
I c

deE
SGBD : Système de Gestion de BasesU
H
L ées
donn

L MO
h r e fE
A c
c

H & H: Research and Training 3 / 41


Introduction

JDBC

Pour se connecter à une base de données


Il nous faut un JDBC (qui varie selon le SGBD utilisé)
JDBC : Java DataBase Connectivity
I c

deE
SGBD : Système de Gestion de BasesU
H
L ées
donn

L MO
h r e fE
c
JDBC ? c A
Une API (interface d’application) créée par Sun Microsystems
Il permet d’accéder aux bases de données en utilisant un driver
JDBC

H & H: Research and Training 3 / 41


Introduction

JDBC

I c

JDBC 8.0.13
EL H
U
MO
Aller sur
L
https://dev.mysql.com/downloads/file/?id=480292
f E l’archive .zip
Télécharger et Dh
c r e
écompresser
c
A

H & H: Research and Training 4 / 41


Introduction

JDBC

Intégrer le driver dans votre projet


I c

E
Faire un clic droit sur le nom du projet et aller
H
Ldans New >
U
Folder
L MO
Renommer le répertoire
r e E puis valider
f lib
A h
cde l’archive décompressée dans lib
c
Copier le .jar

H & H: Research and Training 5 / 41


Introduction

JDBC
Ajouter JDBC au path du projet

Faire clic droit sur .jar qu’on a placé dans lib

Aller dans Build Path et choisir Add to Build Path

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 6 / 41


Introduction

JDBC
Ajouter JDBC au path du projet

Faire clic droit sur .jar qu’on a placé dans lib

Aller dans Build Path et choisir Add to Build Path

I c

Ou aussi
ELH
U
MO
Faire clic droit sur le projet dans Package Explorer et aller dans Properties
L
Properties
f E
hre
Dans Java Build Path, aller dans l’onglet Libraries
c
c A

Cliquer sur Add JARs

Indiquer le chemin du .jar qui se trouve dans le répertoire lib du projet

Appliquer

H & H: Research and Training 6 / 41


Introduction

JDBC
Ajouter JDBC au path du projet

Faire clic droit sur .jar qu’on a placé dans lib

Aller dans Build Path et choisir Add to Build Path

I c

Ou aussi
ELH
U
MO
Faire clic droit sur le projet dans Package Explorer et aller dans Properties
L
Properties
f E
hre
Dans Java Build Path, aller dans l’onglet Libraries
c
c A

Cliquer sur Add JARs

Indiquer le chemin du .jar qui se trouve dans le répertoire lib du projet

Appliquer

Vérifier qu’une section Referenced Libraries a apparu.

H & H: Research and Training 6 / 41


Utilisation

JDBC
Avant de commencer, voici le script SQL qui permet de créer la base de
données utilisée dans ce cours

CREATE DATABASE jdbc;

USE jdbc;
I c

E LH
CREATE TABLE personne(
num INT PRIMARY KEY AUTO_INCREMENT, OU
L M
nom VARCHAR(30),
prenom VARCHAR(30)
ref E
);
c h
c A
SHOW TABLES;

INSERT INTO personne (nom, prenom) VALUES ("Wick", "John"),


("Dalton", "Jack");

SELECT * FROM personne;

H & H: Research and Training 7 / 41


Utilisation

JDBC

Trois étapes I c

H
L cas)
Enotre
Charger le driver JDBC (pour MySQL dansU
la L
Établir la connexion avec E
MO
base de données

c h ref
c A
Créer et exécuter des requêtes SQL

H & H: Research and Training 8 / 41


Utilisation

JDBC

I c

EL H
Avant de commencer
O U
Tous les imports de ce chapitre sontM
fE L de java.sql.*;

c h r e
c
A

H & H: Research and Training 9 / 41


Utilisation

JDBC
Chargement du driver 5
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) { I c

System.out.println(e.getMessage());
ELH
U
}
L MO
r8e f E
c h
Chargement du driver
try { c A
Class.forName("com.mysql.cj.jdbc.Driver");
}
catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
H & H: Research and Training 10 / 41
Utilisation

JDBC

Se connecter à la base de données


Il faut spécifier l’URL (de la forme
I c
jdbc:mysql://hote:port/nombd) H
ELMySQL est installé
U
MO
hote : le nom de l’hôte sur lequel le serveur
L
(dans notre cas localhost ou 127.0.0.1)
Eé par défaut par MySQL est 3306
futilis
r e
port : le port TCP/IP
h
nombd :A le c
nom de la base de données MySQL
c
Il faut aussi le nom d’utilisateur et son mot de passe (qui
permettent de se connecter à la base de données MySQL)

H & H: Research and Training 11 / 41


Utilisation

JDBC

Connexion à la base

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


String user = "root";
String password = "";
Connection connexion = null;
I c

try {
ELH
U
connexion = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
L MO
f E
hre
}
finally {
c
c A
if (connexion != null)
try {

connexion.close();
} catch (SQLException ignore) {
ignore.printStackTrace();
}
}

H & H: Research and Training 12 / 41


Utilisation

JDBC

I c

En cas de problème avec le chargement du driver, modifier l’URL
de connexion ainsi :
ELH
U
String url =
L MO
f E
"jdbc:mysql://localhost:3306/jdbc?useSSL=false&
serverTimezone=UTC";
chre
c A

H & H: Research and Training 13 / 41


Utilisation

JDBC
Préparation et exécution de la requête
// création de la requête (statement)
Statement statement = connexion.createStatement();

// Préparation de la requête
I c

EL H
String request = "SELECT * FROM Personne;";
O U
// Exécution de la requête M
ResultSet result = e fE L
c h r statement.executeQuery(request);

c A

H & H: Research and Training 14 / 41


Utilisation

JDBC
Préparation et exécution de la requête
// création de la requête (statement)
Statement statement = connexion.createStatement();

// Préparation de la requête
I c

EL H
String request = "SELECT * FROM Personne;";
O U
// Exécution de la requête M
ResultSet result = e fE L
c h r statement.executeQuery(request);

c
A
On utilise
executeQuery() pour les requêtes de lecture : select.
executeUpdate() pour les requêtes d’écriture : insert,
update, delete et create.
H & H: Research and Training 14 / 41
Utilisation

JDBC

Récupération des données


while (result.next()) {
I c

// on indique chaque fois le nom de la colonne
ELH
et le type
U
int num = result.getInt("num");
L MO
f E
String nom = result.getString("nom");
chre
String prenom = result.getString("prenom");
c A

System.out.println(num + " " + nom + " " +
prenom);
}

H & H: Research and Training 15 / 41


Utilisation

JDBC

On peut faire aussi


while (result.next()) {
// on peut indiquer aussi l’index de la colonne
I c

et le type
ELH
U
int idPersonne = result.getInt(1);
L MO
E
String nom = result.getString(2);
f
A c hre
String prenom = result.getString(3);

c
pour tous les autres attributs
// pareil
System.out.println(nom + " " + prenom);
}

H & H: Research and Training 16 / 41


Utilisation

JDBC

Pour faire une insertion


Statement statement = connexion.createStatement();
String request = "INSERT INTO Personne (nom,prenom)
VALUES (’Wick’,’John’);";
I c

int nbr = statement.executeUpdate(request);
ELH
if (nbr ! = 0)
U
System.out.println("insertion réussie");
L MO
f E
chre
c A

H & H: Research and Training 17 / 41


Utilisation

JDBC

Pour faire une insertion


Statement statement = connexion.createStatement();
String request = "INSERT INTO Personne (nom,prenom)
VALUES (’Wick’,’John’);";
I c

int nbr = statement.executeUpdate(request);
ELH
if (nbr ! = 0)
U
System.out.println("insertion réussie");
L MO
f E
A c hre
c
La méthode
executeUpdate() retourne

0 en cas d’échec de la requête d’insertion, et 1 en cas de succès

le nombre de lignes respectivement mises à jour ou supprimées

H & H: Research and Training 17 / 41


Utilisation

JDBC
Pour récupérer la valeur de la clé primaire auto-générée
Statement statement = connexion.createStatement();
String request = "INSERT INTO Personne (nom,prenom) VALUES (’
Wick’,’John’);";

I c

primaire
ELH
// on demande le renvoi des valeurs attribuées à la clé

U
MO
statement.executeUpdate(request,Statement.RETURN_GENERATED_KEYS
);
f E L
h re attribuées à l’ensemble de tuples
// on parcourt les valeurs
c
c A = statement.getGeneratedKeys();
ajoutés
ResultSet resultat

// on vérifie s’il contient au moins une valeur


if (resultat.next()) {
System.out.println("Le numéro généré pour cette personne :
" + resultat.getInt(1));
}

H & H: Research and Training 18 / 41


Utilisation

JDBC

Pour éviter les injections SQL, il faut utiliser les requêtes préparées
(pour la consultation, l’ajout, la suppression et la modification)
String request = "INSERT INTO Personne (nom,prenom)
VALUES (?,?);";
I c

PreparedStatement ps = connexion.prepareStatement(
ELH
U
request,PreparedStatement.RETURN_GENERATED_KEYS);
ps.setString(1, "Wick");
L MO
ps.setString(2, "John");
f E
ps.executeUpdate();
chre
c A
ResultSet resultat = ps.getGeneratedKeys();

if (resultat.next())
System.out.println("Le numéro généré pour cette
personne : " + resultat.getInt(1));

H & H: Research and Training 19 / 41


Utilisation

JDBC

Pour éviter les injections SQL, il faut utiliser les requêtes préparées
(pour la consultation, l’ajout, la suppression et la modification)
String request = "INSERT INTO Personne (nom,prenom)
VALUES (?,?);";
I c

PreparedStatement ps = connexion.prepareStatement(
ELH
request,PreparedStatement.RETURN_GENERATED_KEYS);
U
ps.setString(1, "Wick");
L MO
ps.setString(2, "John");
f E
ps.executeUpdate();
chre
c A
ResultSet resultat = ps.getGeneratedKeys();

if (resultat.next())
System.out.println("Le numéro généré pour cette
personne : " + resultat.getInt(1));

Attention à l’ordre des attributs

H & H: Research and Training 19 / 41


Transactions

JDBC

Les transactions
I c

ensemble de requête SQL
EL H
U
MOles requête SQL) soit rien
appliquant le principe soit tout (toutes
L
e
activées par défautravec
E
f MySQL
A h
c ées et gérées par le développeur
pouvant c être désactiv

H & H: Research and Training 20 / 41


Transactions

JDBC

Pour désactiver l’auto-commit


connection.setAutoCommit(false);

I c

ELH
U
Pour valider une transaction
L MO
f E
hre
connection.commit(false);
c
c A

Pour annuler une transaction
connection.rollback(false);

H & H: Research and Training 21 / 41


Transactions

JDBC
Exemple avec les transactions
// désactiver l’auto-commit
connexion.setAutoCommit(false);

String request = "INSERT INTO Personne (nom,prenom) VALUES


I c

(?,?);";
ELH
PreparedStatement ps = connexion.prepareStatement(request,
U
MO
PreparedStatement.RETURN_GENERATED_KEYS);
ps.setString(1, "Wick");
ps.setString(2, "John");
f E L
ps.executeUpdate();
chre
c A

// valider l’insertion
connexion.commit();

ResultSet resultat = ps.getGeneratedKeys();


if (resultat.next())
System.out.println("Le numéro généré pour cette personne :
" + resultat.getInt(1));

H & H: Research and Training 22 / 41


Restructuration du code Classes connexion et dao

JDBC

Organisation du code

Il faut mettre toutes les données (url, nomUtilisateur,


I c

ELH
motDePasse...) relatives à notre connexion dans une classe
connexion U
L MO
E
Pour chaque table de la base de données, on crée une classe
f
hre
java ayant comme attributs les colonnes de cette table
c
c A

Il faut mettre tout le code correspondant à l’accès aux données
(de la base de données) dans des nouvelles classes et interfaces
(qui constitueront la couche DAO : Data Access Object)

H & H: Research and Training 23 / 41


Restructuration du code Classes connexion et dao

La classe MyConnection

package org.eclipse.config;
public class MyConnection {
private static String url = "jdbc:mysql://localhost:3306/jdbc?useSSL=
false&serverTimezone=UTC";
private static String utilisateur = "root";
private static String motDePasse = "";
private static Connection connexion = null;
I c

private MyConnection() {
try {
ELH
U
MO
Class.forName("com.mysql.cj.jdbc.Driver");

motDePasse );
f E L
connexion = DriverManager.getConnection( url, utilisateur,

hre
} catch ( Exception e ) {
c
c A
e.printStackTrace();

}
}

public static Connection getConnection() {
if (connexion == null) {
new MyConnection();
}
return connexion;
}

H & H: Research and Training 24 / 41


Restructuration du code Classes connexion et dao

JDBC

La classe MyConnection (suite)


public static void stop() {
if (connexion != null) {
I c

try {
ELH
U
connexion.close();
L MO
} catch (SQLException e) {
f E
e.printStackTrace();
chre
c A
}
}
}
}

H & H: Research and Training 25 / 41


Restructuration du code Classes connexion et dao

JDBC

La classe Personne
package org.eclipse.model;

public class Personne{


I c

ELH
U
MO
private int num;
private String nom;
f E L
hre
private String prenom;
c
c A

// + getters + setters + constructeur sans param
ètre + constructeur avec 2 paramètres nom et
prénom + constructeur avec 3 paramètres

H & H: Research and Training 26 / 41


Restructuration du code Classes connexion et dao

JDBC

L’interface PersonneDao
package org.eclipse.dao;

import java.util.List;
I c

EL H
U
MO
import org.eclipse.model.Personne;

fE L
h r e
public interface PersonneDao {
c save(Personne personne);

void
A
Personne
c remove(Personne personne);
Personne update(Personne personne);
Personne findById(int id);
List<Personne> getAll();
}

H & H: Research and Training 27 / 41


Restructuration du code Classes connexion et dao

La classe PersonneDaoImpl définie dans org.eclipse.dao

public class PersonneDaoImpl implements PersonneDao {


@Override
public Personne save(Personne personne) {
Connection c = MyConnection.getConnection();
if (c != null) {
try {
PreparedStatement ps = c.prepareStatement("insert into
I c

RETURN_GENERATED_KEYS);
ELH
personne (nom,prenom) values (?,?); ", PreparedStatement.

ps.setString(1, personne.getNom());
U
ps.setString(2, personne.getPrenom());
L MO
ps.executeUpdate();
f E
hre
ResultSet resultat = ps.getGeneratedKeys();
if (resultat.next()) {
c
c A
personne.setNum(resultat.getInt(1));

}

return personne;

} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}

H & H: Research and Training 28 / 41


Restructuration du code Classes connexion et dao

Exemple de la méthode save en utilisant les transactions

public Personne save(Personne personne) {


Connection c = MyConnection.getConnection();
if (c != null) {
try {
c.setAutoCommit(false);
PreparedStatement ps = c.prepareStatement("insert into

c

personne (nom,prenom) values (?,?); ", PreparedStatement.
I
RETURN_GENERATED_KEYS);
ps.setString(1, personne.getNom());
ELH
ps.setString(2, personne.getPrenom());
U
ps.executeUpdate();
L MO
E
ResultSet resultat = ps.getGeneratedKeys();
f
hre
if (resultat.next()) {
c.commit();
c
c A
personne.setNum(resultat.getInt(1));

}

return personne;

} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}

H & H: Research and Training 29 / 41


Restructuration du code Classes connexion et dao

JDBC
La classe PersonneDaoImpl (suite)

@Override
public Personne findById(int id) {
Personne personne = null;
Connection c = MyConnection.getConnection();
if (c != null) {
I c

try {

ELH
PreparedStatement ps = c.prepareStatement("select * from
U
MO
personne where num = ?; ");
ps.setInt(1, id);

E L
ResultSet r =ps.executeQuery();
f
hre
if (r.next())

c
personne = new Personne(r.getInt("num"),r.getString("nom"),r.

c A
getString("prenom"));

} catch (SQLException e) {
e.printStackTrace();
}
}
return personne;
}
}

Il faut implémenter toutes les méthodes de l’interface PersonneDao


H & H: Research and Training 30 / 41
Restructuration du code Classes connexion et dao

Le Main pour tester toutes ces classes


package org.eclipse.classes;

import org.eclipse.dao.PersonneDaoImpl;
import org.eclipse.model.Personne;

public class Main {


I c
public static void main(String args []) { L
E H
O U
L M =("Wick","John");
PersonneDaoImpl personneDaoImpl
Personne personne = newE
new PersonneDaoImpl();

ref = personneDaoImpl.save(personne);
Personne

A c h
Personne insertedPersonne

c
if (insertedPersonne != null)
System.out.println("personne numéro " + insertedPersonne.
getNum() + " a été insérée");
else
System.out.println("problème d’insertion");
}
}

H & H: Research and Training 31 / 41


Restructuration du code Classes connexion et dao

JDBC

I c
Remarque EL H
U
Oautres méthodes de
M
N’oublions pas d’implémenter les quatre
L
l’interface Dao
h r e fE
A c
c

H & H: Research and Training 32 / 41


Restructuration du code Classes connexion et dao

JDBC

Utilisation de la généricité avec les DAO


I c
H
EL tables de la
Nous devons créer autant d’interfaces DAO que
U
bases de données
L MO
Pour éviter cela, on peut E une seule interface Dao avec un
ef utiliser
rtoutes
A h
type génériquecque les classes d’accès aux données
doivent cl’implémenter.

H & H: Research and Training 33 / 41


Restructuration du code Classes connexion et dao

JDBC

L’interface Dao
package org.eclipse.dao;

I c

import java.util.List;
ELH
public interface Dao <T> { MO
U
f E L
c h re obj);
T save(T obj);
void remove(T
A obj);
Tcupdate(T

T findById(int id);
List<T> getAll();
}

H & H: Research and Training 34 / 41


Restructuration du code Classes connexion et dao

JDBC

La classe PersonneDaoImpl
I c

package org.eclipse.dao;
EL H
U
MO Dao<Personne>{
public class PersonneDaoImpl implements
L
...
h r e fE
A c
c
pour le reste
Rien ne change

H & H: Research and Training 35 / 41


Restructuration du code DataSource et fichier de propriétés

JDBC

Encore de la restructuration du code


I c

H
Mettre les données (url, nomUtilisateur, motDePasse...) relatives à
EL
U
notre connexion dans un fichier de propriétés que nous appelons
MO
db.properties (utilisé par certain framework comme Spring)
L
f E
A c hre
Créer une nouvelle classe (DataSourceFactory) qui va lire et
construire les différentes propriétés de la connexion
c
Utiliser DataSourceFactory dans MyConnection

H & H: Research and Training 36 / 41


Restructuration du code DataSource et fichier de propriétés

JDBC

Le fichier db.properties situé à la racine du projet (ayant la


I c

forme clé = valeur, le nom de la clé est à choisir par
l’utilisateur) EL H
U
L MO
url=jdbc:mysql://localhost:3306/jdbc?useSSL=false&
serverTimezone=UTCf E
username=root chre
c A
password=root

H & H: Research and Training 37 / 41


Restructuration du code DataSource et fichier de propriétés

Créons la classe MyDataSourceFactory dans org.eclipse.config


import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import javax.sql.DataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

public class MyDataSourceFactory {


public static DataSource getMySQLDataSource() {
I c

Properties props = new Properties();
ELH
FileInputStream fis = null;
U
MysqlDataSource mysqlDataSource = null;
try {
L MO
f E
hre
fis = new FileInputStream("db.properties");
props.load(fis);
c
c A
mysqlDataSource = new MysqlDataSource();

mysqlDataSource.setURL(props.getProperty("url"));
mysqlDataSource.setUser(props.getProperty("username"));
mysqlDataSource.setPassword(props.getProperty("password"));
} catch (IOException e) {
e.printStackTrace();
}
return mysqlDataSource;
}
}
H & H: Research and Training 38 / 41
Restructuration du code DataSource et fichier de propriétés

JDBC

I c
Remarque H
EpasL le driver
Dans MyDataSourceFactory, on ne pr O U
écise
com.mysql.jdbc.Driver car Lon M
f Elui même le driver.
utilise un objet de la classe

c h e
MysqlDataSource quircharge

c
A

H & H: Research and Training 39 / 41


Restructuration du code DataSource et fichier de propriétés

La classe MyConnection du package org.eclipse.config

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;

public class MyConnection {

private static Connection connexion = null;


I c

private MyConnection() {
ELH
U
MO
DataSource dataSource = MyDataSourceFactory.getMySQLDataSource();
L
try {
f E
hre
connexion = dataSource.getConnection();

c
} catch (SQLException e) {

c A
e.printStackTrace();

}
}

public static Connection getConnection() {
if (connexion == null) {
new MyConnection();
}
return connexion;
}

H & H: Research and Training 40 / 41


Restructuration du code DataSource et fichier de propriétés

Relançons le Main et vérifier que tout fonctionne correctement


package org.eclipse.classes;

import org.eclipse.dao.PersonneDaoImpl;
import org.eclipse.model.Personne;

public class Main {


I c
public static void main(String args []) { L
E H
O U
L M =("Wick","John");
PersonneDaoImpl personneDaoImpl
Personne personne = newE
new PersonneDaoImpl();

ref = personneDaoImpl.save(personne);
Personne

A c h
Personne insertedPersonne

c
if (insertedPersonne != null)
System.out.println("personne numéro " + insertedPersonne.
getNum() + " a été insérée");
else
System.out.println("problème d’insertion");
}
}

H & H: Research and Training 41 / 41

Vous aimerez peut-être aussi