SlideShare une entreprise Scribd logo
Java et bases de données
JDBC - Stratégies - Pattern DAO - Hibernate
Version du 25/08/2015
JDBC
• API orientée objet unifiée d’accès aux SGBD
• Soumission de requête via un driver
• Accès aux SGBD
• Soit par un driver JDBC adapté
• Soit par des passerelles
• (ex : passerelle JDBC->ODBC)
Process de requétage
1. Chargement du driver
2. Connexion à la base
3. Création de Statement
• Envoi de la requête
• Avec ou sans préparation
4. Prise en compte du résultat éventuel
• Via un ResultSet
5. Fermeture de la connexion
1 - Chargement du
driver
import java.sql.*;
class Cnx
{
public Cnx()
{
try 

{
Class.forName("com.mysql.jdbc.Driver").newInstance();
}
catch (ClassNotFoundException e)
{
System.out.println("Driver spécifié non trouvé");
}
}

}
Accès direct au driver
par une chaîne de
caractères
On utilise
les prototypes
de java.sql
2 - Connexion à la base
Connection cnx;
try
{
cnx=DriverManager.getConnection
("jdbc:mysql://localhost/Bibliotheque","user","passwd");
}
catch (SQLException e)
{
System.out.println("Impossible de se connecter sur la base") ;
System.out.println(e) ;
}
Comment récupérer la
connexion ?
• Il faut éviter à tout prix de relancer X fois la
procédure “chargement driver / connexion”
• Outil de préservation d’unicité : le singleton
Connection cnx=Cnx.getCnx().getConnection();
• Dans un contexte Web, on peut passer par les
séquences d’initialisations du serveur
• Utilisation de Pools de connexion
3 - Création de
Statement
// L’instance de Statement est générée par l’objet connexion
Statement st=cnx.createStatement();


// Exemple de requête avec résultat

ResultSet rs=st.executeQuery("SELECT * FROM table");



// Exemple de requête sans résultat

st.executeUpdate

("DELETE FROM table WHERE num = 1");

4 - Exploitation des
résultats
• Après le SELECT : Exploitation du ResultSet
• Accès aux colonnes par :
• Index (à partir de 1)
XXX getXXX(int index);
• Nom de colonne
XXX getXXX(String nomCol);
Parcours d’un ResultSet
• On utilise la méthode next();
• Certains drivers intègrent d’autres
méthodes :
• previous()
• relative(int mv)
• Toutes retournent un booléan pour inclusion
directe dans un while(...)
Exemples de parcours
d’un ResultSet
while(rs.next())

{

int num=rs.getInt(“num”);

String titre=rs.getString(“titre”);

}
while(rs.next())

{

int num=rs.getInt(1);

String titre=rs.getString(2);

}
5 - Fin de connexion
• Il faut penser à fermer tous les objets
rs.close();

st.close();

cnx.close();
• Il est important de fermer la connexion
• Nombre d’accès limités par SGBD
• Ne pas monopoliser ces ressources !
• Cas particulier : si la connexion est dans un
singleton
Récupération d’une clé
générée
• Certaines tables génèrent automatiquement
leur clé lors d’un INSERT
• (auto_increment sous MySQL)
• Récupération de la clé après le INSERT
• Avec JDBC>=3 :
statement.getGeneratedKeys()
• Sous MySQL : SELECT LAST_INSERT_ID
• Autre SGBD : voir driver propriétaire
Récupération de la clé
String req=”INSERT …“;
st.executeUpdate(sql);
// Récupération avec Statement.getGeneratedKeys()
rs = st.getGeneratedKeys();
if (rs.next())
cle = rs.getInt(1);
// Récupération avec MySQL LAST_INSERT_ID()
rs = st.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next())
cle = rs.getInt(1);
Les statement préparés
• Permet de faciliter l’écriture de requêtes
complexes
• Stockées dans le SGBD, seuls les paramètres
sont envoyés d’un appel à l’autre
• Permet d’éviter divers problèmes de
syntaxe...
• ...et divers problèmes de sécurité
• + quelques bénéfices de performance
Exemple de
PreparedStatement
// Création du Statement
PreparedStatement phrase= cnx.prepareStatement(
 " INSERT into TABLE (chaine, entier, reel) VALUES (?,?,?) ");


// Mise en place des paramètres
phrase.setString(1, "uneChaine");
phrase.setInt(2, 56);
phrase.setDouble(3, 3.314456);


// Exécution de la requête
phrase.executeUpdate();
Liste de
paramètres
Intérêts du
PreparedStatement
• Légèrement plus efficace (pré-exécution sur
le SGBD)
• Evite des problèmes de syntaxe
• Oublis de ‘ ‘ pour des chaînes,‘ intempestifs
• Protège (partiellement) des injections SQL
• Insertion illicites de requêtes
Traitements batchs
Connection connection = ... ;
Statement statement = connection.createStatement();
if(connection.getMetaData().supportsBatchUpdates()){
connection.setAutoCommit(false);
statement.clearBatch(); //on supprime les anciens batch
statement.addBatch("INSERT ....");
statement.addBatch("UPDATE ...");
statement.addBatch("...");
int[] resultat = statement.executeBatch();
//voir les différents types de retour possibles
connection.commit();
connection.setAutoCommit(false);
}
Intégration des accès à la
base dans les objets
• Un des rôles des objets métiers est de faire la
liaison avec la base de données
• 3 cas principaux sont à traiter :
• Liaison simple une instance = un enreg
• Instances encapsulant des listes
• Structures hiérarchiques (héritage)
Exemple d’intégration
d’appels à la base
• Une classe User utilisée dans un site Web
• On peut :
• Se connecter avec un login/mot de passe
• A vérifier avec un SELECT
• S’enregistrer en donnant un login, un mot
de passe, un nom, une adresse...
• A concrétiser avec un INSERT INTO...
Structure de la classe
User
• C’est un objet CRUD 

(Create/Read/Update/Delete)
• Exemple de création/
enregistrement :

User u=new User();

u.setNom(“.....”);

...

u.insert();
User
login
password
nom
select(login,password)
insert()
update()
delete()
On verra plus
tard qu’il vaut mieux
utiliser un pattern
DAO
Procédure de login
• Comment faire à la fois :
• Contrôler si un login/pass est correct
• Charger les données du user (nom...)
• Empêcher qu’une instance de User soit
incohérente en mémoire (login/pass
incorrect mais encapsulés dans un objet)
• Solution : on utilise un constructeur
• Avec une lancée d’exception éventuelle
Constructeur de User
public class User()

{

public User(String login, String pwd) 

throws UserInexistantException()

{

String sql=”SELECT nom FROM user

WHERE login=’”+login+”’ AND pwd=’”+pwd+”’”;

if(rs.next()) // le login existe

this.nom=rs.getString(“nom”); // on charge les données

else // le login n’existe pas

throw new LoginIncorrectException(login);

}
Exploitation de
liaisons 1-N
• En objet : c’est un attribut qui contient des
instances d’autres objets
• En SGBD : c’est le résultat d’une requête avec
une clé secondaire
• Il va donc falloir faire une requête qui va
remplir la liste
• Problème : comment instancier chacun des
éléments de la liste ?
Exemple de liste en
objet
public class Catalogue
{
private ArrayList<Produit> liste;
public void rech(String texte)
{
// remplissage de la liste
}
…
}
public class Produit
{
private int cle;
private String nom;
...
public void load(int cle)
{
// lecture d’un enregistrement
}
}
Remplissage
“procédural”
public void rech(String texte)
{
sql=”SELECT * FROM produit WHERE ...”;
while(...)
{
Produit p=new Produit();
p.setNom(rs.getString(“nom”));
...

liste.add(p);
}
}
Problème :
on gère la lecture d’un produit
en dehors de la classe Produit
-> non respect de la notion 

d’encapsulation
Remplissage “objet”
public void rech(String texte)
{
sql=”SELECT cle FROM produit WHERE ...”;
while(...)
{
cle=rs.getInt(“cle”);
Produit p=new Produit();
p.load(cle);
liste.add(p);
}
}
Problème :
On génère un grand nombre
de requête (N+1 requêtes,
N étant le nombre de produits)
Solution mixte
public void rech(String texte)
{
sql=”SELECT * FROM produit WHERE ...”;
while(...)
{
Produit p=new Produit();
p.load(rs);
liste.add(p);
}
}
Dans cette solution, on passe
à ‘load’ directement le ResultSet
“rs” afin de traiter la requête à
la source
L’héritage dans un
modèle relationnel
• Problématique : il n’est pas possible de définir
directement une structure d’héritage dans un
système de tables
• Plusieurs solutions sont possibles :
• 1 table regroupant tout
• 1 table par classe fille
• 1 table par classe fille + 1 table pour la
classe mère
Modèle à une table
• A partir d’une hiérarchie de classe Produit ->
Cd ou Livre :
Table produit :
-refprod
-type

-nom
-prix
-dureecd
-nbpageslivres La table contient à la
fois les infos du CD, et celles
du livre
Cette solution est
valable si CD et Livre ont peu
de données divergentesLe type est
encodé dans un
champ
Une table par classe fille
sans factorisation
• A partir d’une hiérarchie de classe Produit ->
Cd ou Livre :
La table Livre contient
toutes les données
d’un livre
Cette solution facilite les requêtes mais
complique les recherches
inter-catégories
Table CD :
-refprod
-nom
-prix
-dureecd
Table Livre :
-refprod
-nom
-prix
-nbpages
1 table par classe fille +
1 table pour classe mère
• A partir d’une hiérarchie de classe Produit ->
Cd ou Livre :
Table Produit :
-refprod
-type

-nom
-prix
La table Livre contient
uniquement les données
propres au livre
Cette solution concilie factorisation
et particularité des types de produits
Table CD :
-refprod
-dureecd
Table Livre :
-refprod
-nbpages
Lecture base d’une
classe polymorphe
• On passe par une Factory qui va délivrer
suivant les cas une instance de CD, de Livre...
Produit p=ProduitFactory.getProduit(int cle);
‘p’ sera en fait une
instance de CD, de Livre..
Factory modèle à 1 table
public static Produit getProduit(int cle)
{
Produit p=null;
sql=”SELECT * FROM produit WHERE ...”;
if(...)
{
type=rs.getString(“type”);
if(type.equals(“cd”))
{
p=new CD();
p.load(rs);
}
}
return p;
}
Factory modèle à N tables
public static Produit getProduit(int cle)
{
Produit p=null;
p=new CD();
if(!p.load(cle))
{
p=new Livre();
if(!p.load(cle))
{
...
}
else p=null;
}
return p;
}
On ne peut que faire des
tests en cascade
Factory modèle à N tables +1
public static Produit getProduit(int cle)
{
Produit p=null;
sql=”SELECT * FROM produit WHERE ...”;
if(...)
{
type=rs.getString(“type”);
if(type.equals(“cd”))
{
p=new CD();
p.load(rs);
}
}
return p;
}
C’est
dans chacune des méthodes
“load()” que l’on va faire une jointure
entre les données ‘mère’ et
‘fille’
Conclusion sur ces
différents scénarios
• Le scénario « 1 table » est peu satisfaisant
d’un point de vue SGBD, mais finalement
limpide à gérer par la Factory
• Le scénario 2 est un peu trop ‘batard’ pour
être utile
• Le scénario « N tables +1 » est un bon
compromis difficulté/propreté de structure
• D’autres structures sont envisageables (ex :
tables décrivant des listes de champs)
Pattern DAO
• Data Access Object
• Permet de résoudre plusieurs problèmes :
• Eviter que les instances d’objets métiers
soient trop lourdes en mémoire
• Permettre des traitements différenciés
suivant les supports (lecture dans un fichier
texte, dans un XML, dans une base…)
• Séparer la partie métier d’aspects beaucoup
plus techniques
Implémentation d’un DAO
UserDAO<User,Integer>
User select(login,password)
insert(User)
update(User)
User
login
password
nom
UserMySQLDAO<User,Integer>
Connection cnx
User select(Integer i)
User select(login,password)
insert(User)
update(User)
DAO<T,U>
<<abstract>>
T select(U id)
insert(T)
update(T)
Utilisation d’un objet
DAO
User u=new User();
u.setNom(« Leponge »);
u.setPrenom(« Bob »);
UserDAO dao = new UserMySQLDAO(cnx);
dao.insert(u);
Hibernate
Persistence d’objet en Java
Rendre un objet
persistant
• Pour rendre un objet persistant, il suffit de le lier à
la session
• session.save(objet);
• La clé pourra éventuellement être générée
automatiquement, et délivrée par save() :
• Long cle=(Long)session.save(objet);
• (clé déclarée assigned dans le HBM)
• Cette clé sera également dans objet.getRef()
Sauvegarde par
saveOrUpdate
• Si la clé a été renseignée dans l’objet :
• Si la clé existe en base : UPDATE
• Si la clé n’existe pas : INSERT
• Si la clé n’a pas été renseignée : INSERT
• Si l’objet existe en base et n’a pas été modifié
en mémoire : pas de requête générée
Chargement d’un objet
Client c=(Client)session.load(Client.class,new Long(12));
• ou :
Client c=new Client();

session.load(c,new Long(12));
• version sans lancement d’exception (renvoie null si l’objet
n’existe pas)
Client c=

(Client)session.get(Client.class,new Long(12));

if(c==null)

c=new Client();
Requêtage HQL
Query q=session.createQuery(“...”);

q.setString(0,”..”);

q.setInt(1,”...”);

List l=q.list(); // émission de la requête
• S’il n’y a qu’un résultat :
Client c=(Client)q.uniqueResult();
Paramètres d’une
requête• Par numéro :
FROM Client WHERE nom=? AND age=?
q.setString(0,”Dupont”); // commence à 0
• Par nom :
FROM Client WHERE nom=:nom AND age=:age
q.setString(“nom”,”Dupont”);
• Listés :
FROM Client WHERE nom IN (:liste)
q.setParameterList(“liste”,unTableau);
Récupération plusieurs
objets d’un coup
Query q = sess.createQuery(
"SELECT facture,client FROM Facture facture 

JOIN Client facture.client client");

List l=q.list();

Iterator it=l.iterator();
while ( it.hasNext() ) {
Object[] tuple = (Object[]) it.next();
Facture f= tuple[0];
Client c = tuple[1];
....
}
Association N-1
unidirectionnelle
<class name="Item">
<id name="ref" column="refitem">
<generator class="native"/>
</id>

<many-to-one name=”prod” class=”Produit”>
<column="refprod"
not-null="true"/>

</many-to-one>
</class>
<class name="Produit">
<id name="ref" column="refprod">
<generator class="native"/>
</id>
</class>
create table Item ( 

refitem bigint not null primary key

refprod bigint not null )
create table Produit ( 

refprod bigint not null primary key)
public class Item ( 

private Long ref;

private Produit prod;
)
public class Produit (
private Long ref;

)
Association 1-1
unidirectionnelle
<class name="Client">
<id name="ref" column="refcli">
<generator class="native"/>
</id>

<many-to-one name=”panier” class=”Panier”>
<column="refpanier"

unique=”true”
not-null="true"/>

</many-to-one>
</class>
<class name="Panier">
<id name="ref" column="refpanier">
<generator class="native"/>
</id>
</class>
create table Client ( 

refcli bigint not null primary key

refpanier bigint not null )
create table Panier ( 

refpanier bigint not null primary key)
public class Client ( 

private Long ref;

private Panier panier;
)
public class Panier (
private Long ref;

)
Association 1-N
unidirectionnelle
<class name="Client">
<id name="ref" column="refclient">
<generator class="native"/>
</id>
<set name="factures">
<key column="refclient"
not-null="true"/>
<one-to-many class="Facture"/>
</set>
</class>
<class name="Facture">
<id name="ref" column="reffacture">
<generator class="native"/>
</id>
</class>
create table Client ( 

refclient bigint not null primary key )
create table Facture ( 

reffacture bigint not null primary key,

refclient bigint not null )
public class Client ( 

private Long ref;

private List factures;
)
public class Facture (
private Long ref;

)
Représentation
d’héritage avec une table
<class name="Produit" table="produit" abstract=”true” discriminator-value=”-”>
<id name="ref" column="ref">
<generator class="native"/>
</id>
<discriminator column="type" type="character"/>
<property name="titre"/>


<subclass name="Livre" discriminator-value="L">
<property name="nbpages"/>
</subclass>
<subclass name="CD" discriminator-value="C">
<property name="duree"/>
<property name="maisondisque"/>
</subclass>
</class>
create table produit (
ref BIGINT not null,
type CHAR(1) not null,
titre VARCHAR(255),
duree FLOAT,
maisondisque VARCHAR(255),
nbpages INTEGER,
primary key (ref)
)
Représentation d’héritage
avec plusieurs tables
<class name="Produit" table="produit" abstract=”true”>
<id name="ref" column="refprod">
<generator class="native"/>
</id>
<discriminator column="type" type="character"/>
<property name="titre"/>


<join-subclass name="CD" table="cd">
<key column="refprod"/>
<property name="maisondisque"/>
</subclass>
</class>
create table produit (
ref BIGINT not null,
type CHAR(1) not null,
titre VARCHAR(255),
duree FLOAT,
maisondisque VARCHAR(255),
nbpages INTEGER,
primary key (ref)
)
create table cd (
ref BIGINT not null,
maisondisque VARCHAR(255),
primary key (ref)
)

Contenu connexe

Tendances

Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
Daniel Rene FOUOMENE PEWO
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
ENSET, Université Hassan II Casablanca
 
Cours javascript v1
Cours javascript v1Cours javascript v1
Cours javascript v1
TheBest Icanbe
 
cours javascript.pptx
cours javascript.pptxcours javascript.pptx
cours javascript.pptx
YaminaGh1
 
Support NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDBSupport NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDB
ENSET, Université Hassan II Casablanca
 
Expose linux gestion des processus
Expose linux  gestion des processusExpose linux  gestion des processus
Expose linux gestion des processus
Fatima Zahra Fagroud
 
Tp3 - Application SOA avec BPEL
Tp3 - Application SOA avec BPELTp3 - Application SOA avec BPEL
Tp3 - Application SOA avec BPEL
Lilia Sfaxi
 
Les règles de passage
Les règles de passageLes règles de passage
Les règles de passage
marwa baich
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdf
slimyaich3
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
Aziz Darouichi
 
UML Part2- diagramme des uses cases_mansouri
UML Part2- diagramme des uses cases_mansouriUML Part2- diagramme des uses cases_mansouri
UML Part2- diagramme des uses cases_mansouri
Mansouri Khalifa
 
Initiation à l'algorithmique
Initiation à l'algorithmiqueInitiation à l'algorithmique
Initiation à l'algorithmique
Abdoulaye Dieng
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en Java
Aziz Darouichi
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
Lhouceine OUHAMZA
 
Java 8 - collections et stream
Java 8 - collections et streamJava 8 - collections et stream
Java 8 - collections et stream
Franck SIMON
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
ENSET, Université Hassan II Casablanca
 
Cours php & Mysql - 1ére partie
Cours php & Mysql - 1ére partieCours php & Mysql - 1ére partie
Cours php & Mysql - 1ére partie
kadzaki
 
Introduction à Laravel
Introduction à LaravelIntroduction à Laravel
Introduction à Laravel
Abdoulaye Dieng
 
Nouveautés de java 8
Nouveautés de java 8Nouveautés de java 8
Nouveautés de java 8
Florian Beaufumé
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8
Antoine Rey
 

Tendances (20)

Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
 
Support POO Java première partie
Support POO Java première partieSupport POO Java première partie
Support POO Java première partie
 
Cours javascript v1
Cours javascript v1Cours javascript v1
Cours javascript v1
 
cours javascript.pptx
cours javascript.pptxcours javascript.pptx
cours javascript.pptx
 
Support NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDBSupport NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDB
 
Expose linux gestion des processus
Expose linux  gestion des processusExpose linux  gestion des processus
Expose linux gestion des processus
 
Tp3 - Application SOA avec BPEL
Tp3 - Application SOA avec BPELTp3 - Application SOA avec BPEL
Tp3 - Application SOA avec BPEL
 
Les règles de passage
Les règles de passageLes règles de passage
Les règles de passage
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdf
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
UML Part2- diagramme des uses cases_mansouri
UML Part2- diagramme des uses cases_mansouriUML Part2- diagramme des uses cases_mansouri
UML Part2- diagramme des uses cases_mansouri
 
Initiation à l'algorithmique
Initiation à l'algorithmiqueInitiation à l'algorithmique
Initiation à l'algorithmique
 
Chapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en JavaChapitre 11: Expression Lambda et Référence de méthode en Java
Chapitre 11: Expression Lambda et Référence de méthode en Java
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
 
Java 8 - collections et stream
Java 8 - collections et streamJava 8 - collections et stream
Java 8 - collections et stream
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
 
Cours php & Mysql - 1ére partie
Cours php & Mysql - 1ére partieCours php & Mysql - 1ére partie
Cours php & Mysql - 1ére partie
 
Introduction à Laravel
Introduction à LaravelIntroduction à Laravel
Introduction à Laravel
 
Nouveautés de java 8
Nouveautés de java 8Nouveautés de java 8
Nouveautés de java 8
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8
 

Similaire à JAVA, JDBC et liaison base de données

Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbc
abderrahim marzouk
 
Android ORMLite
Android   ORMLiteAndroid   ORMLite
Android ORMLite
Franck SIMON
 
Java Database Connectivity
Java Database ConnectivityJava Database Connectivity
Java Database Connectivity
Korteby Farouk
 
Cours_Java.pdf
Cours_Java.pdfCours_Java.pdf
Cours_Java.pdf
MohamedCheikhAhmed
 
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Loic Yon
 
Présentaion sur le modéle JDBC JEE .pptx
Présentaion sur le modéle JDBC JEE .pptxPrésentaion sur le modéle JDBC JEE .pptx
Présentaion sur le modéle JDBC JEE .pptx
salmachtioui1
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbcKarim Amane
 
JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java
Youness Boukouchi
 
GWT : under the hood
GWT : under the hoodGWT : under the hood
GWT : under the hoodsvuillet
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scala
SOAT
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScript
Abdoulaye Dieng
 
Présentation nouveauté java7
Présentation nouveauté java7Présentation nouveauté java7
Présentation nouveauté java7
Cynapsys It Hotspot
 
Eric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharpEric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharp
MSDEVMTL
 
Accès aux bases de données via jdbc
Accès aux bases de données via jdbcAccès aux bases de données via jdbc
Accès aux bases de données via jdbc
Rachid Lajouad
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScript
Abdoulaye Dieng
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - Xebia
Olivier BAZOUD
 
Hibernate
HibernateHibernate
Hibernate
Maher Megadmini
 

Similaire à JAVA, JDBC et liaison base de données (20)

Marzouk une introduction à jdbc
Marzouk une introduction à jdbcMarzouk une introduction à jdbc
Marzouk une introduction à jdbc
 
Android ORMLite
Android   ORMLiteAndroid   ORMLite
Android ORMLite
 
Jdbc
JdbcJdbc
Jdbc
 
Java Database Connectivity
Java Database ConnectivityJava Database Connectivity
Java Database Connectivity
 
Cours_Java.pdf
Cours_Java.pdfCours_Java.pdf
Cours_Java.pdf
 
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
Java - Support etudiant - Tronc Commun Deuxième année ISIMA - 2018
 
Présentaion sur le modéle JDBC JEE .pptx
Présentaion sur le modéle JDBC JEE .pptxPrésentaion sur le modéle JDBC JEE .pptx
Présentaion sur le modéle JDBC JEE .pptx
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbc
 
JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java JDBC: Gestion des bases de données en Java
JDBC: Gestion des bases de données en Java
 
Jdbc
JdbcJdbc
Jdbc
 
GWT : under the hood
GWT : under the hoodGWT : under the hood
GWT : under the hood
 
Introduction à scala
Introduction à scalaIntroduction à scala
Introduction à scala
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScript
 
Présentation nouveauté java7
Présentation nouveauté java7Présentation nouveauté java7
Présentation nouveauté java7
 
Eric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharpEric Moreau: AOP in .Net sing PostSharp
Eric Moreau: AOP in .Net sing PostSharp
 
Part1
Part1Part1
Part1
 
Accès aux bases de données via jdbc
Accès aux bases de données via jdbcAccès aux bases de données via jdbc
Accès aux bases de données via jdbc
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScript
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - Xebia
 
Hibernate
HibernateHibernate
Hibernate
 

Plus de Jean David Olekhnovitch

Designs Patterns
Designs PatternsDesigns Patterns
Designs Patterns
Jean David Olekhnovitch
 
Python
PythonPython
Internet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applicationsInternet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applications
Jean David Olekhnovitch
 
Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2
Jean David Olekhnovitch
 
Agilité et Entreprise libérée
Agilité et Entreprise libéréeAgilité et Entreprise libérée
Agilité et Entreprise libérée
Jean David Olekhnovitch
 
Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?
Jean David Olekhnovitch
 
Java - implémentation des concepts objets
Java - implémentation des concepts objetsJava - implémentation des concepts objets
Java - implémentation des concepts objetsJean David Olekhnovitch
 
Java - notions de bases pour développeur
Java - notions de bases pour développeurJava - notions de bases pour développeur
Java - notions de bases pour développeurJean David Olekhnovitch
 
Internet mobile
Internet mobileInternet mobile
Internet mobile
Jean David Olekhnovitch
 
Ecommerce
EcommerceEcommerce
Genielogiciel
GenielogicielGenielogiciel

Plus de Jean David Olekhnovitch (12)

Designs Patterns
Designs PatternsDesigns Patterns
Designs Patterns
 
Python
PythonPython
Python
 
Internet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applicationsInternet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applications
 
Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2Développement web mobile avec IONIC 2
Développement web mobile avec IONIC 2
 
Agilité et Entreprise libérée
Agilité et Entreprise libéréeAgilité et Entreprise libérée
Agilité et Entreprise libérée
 
Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?
 
Java - implémentation des concepts objets
Java - implémentation des concepts objetsJava - implémentation des concepts objets
Java - implémentation des concepts objets
 
Java - notions de bases pour développeur
Java - notions de bases pour développeurJava - notions de bases pour développeur
Java - notions de bases pour développeur
 
Internet mobile
Internet mobileInternet mobile
Internet mobile
 
Ecommerce
EcommerceEcommerce
Ecommerce
 
Genielogiciel
GenielogicielGenielogiciel
Genielogiciel
 
Plan d'action WAI
Plan d'action WAIPlan d'action WAI
Plan d'action WAI
 

JAVA, JDBC et liaison base de données

  • 1. Java et bases de données JDBC - Stratégies - Pattern DAO - Hibernate Version du 25/08/2015
  • 2. JDBC • API orientée objet unifiée d’accès aux SGBD • Soumission de requête via un driver • Accès aux SGBD • Soit par un driver JDBC adapté • Soit par des passerelles • (ex : passerelle JDBC->ODBC)
  • 3. Process de requétage 1. Chargement du driver 2. Connexion à la base 3. Création de Statement • Envoi de la requête • Avec ou sans préparation 4. Prise en compte du résultat éventuel • Via un ResultSet 5. Fermeture de la connexion
  • 4. 1 - Chargement du driver import java.sql.*; class Cnx { public Cnx() { try 
 { Class.forName("com.mysql.jdbc.Driver").newInstance(); } catch (ClassNotFoundException e) { System.out.println("Driver spécifié non trouvé"); } }
 } Accès direct au driver par une chaîne de caractères On utilise les prototypes de java.sql
  • 5. 2 - Connexion à la base Connection cnx; try { cnx=DriverManager.getConnection ("jdbc:mysql://localhost/Bibliotheque","user","passwd"); } catch (SQLException e) { System.out.println("Impossible de se connecter sur la base") ; System.out.println(e) ; }
  • 6. Comment récupérer la connexion ? • Il faut éviter à tout prix de relancer X fois la procédure “chargement driver / connexion” • Outil de préservation d’unicité : le singleton Connection cnx=Cnx.getCnx().getConnection(); • Dans un contexte Web, on peut passer par les séquences d’initialisations du serveur • Utilisation de Pools de connexion
  • 7. 3 - Création de Statement // L’instance de Statement est générée par l’objet connexion Statement st=cnx.createStatement(); 
 // Exemple de requête avec résultat
 ResultSet rs=st.executeQuery("SELECT * FROM table");
 
 // Exemple de requête sans résultat
 st.executeUpdate
 ("DELETE FROM table WHERE num = 1");

  • 8. 4 - Exploitation des résultats • Après le SELECT : Exploitation du ResultSet • Accès aux colonnes par : • Index (à partir de 1) XXX getXXX(int index); • Nom de colonne XXX getXXX(String nomCol);
  • 9. Parcours d’un ResultSet • On utilise la méthode next(); • Certains drivers intègrent d’autres méthodes : • previous() • relative(int mv) • Toutes retournent un booléan pour inclusion directe dans un while(...)
  • 10. Exemples de parcours d’un ResultSet while(rs.next())
 {
 int num=rs.getInt(“num”);
 String titre=rs.getString(“titre”);
 } while(rs.next())
 {
 int num=rs.getInt(1);
 String titre=rs.getString(2);
 }
  • 11. 5 - Fin de connexion • Il faut penser à fermer tous les objets rs.close();
 st.close();
 cnx.close(); • Il est important de fermer la connexion • Nombre d’accès limités par SGBD • Ne pas monopoliser ces ressources ! • Cas particulier : si la connexion est dans un singleton
  • 12. Récupération d’une clé générée • Certaines tables génèrent automatiquement leur clé lors d’un INSERT • (auto_increment sous MySQL) • Récupération de la clé après le INSERT • Avec JDBC>=3 : statement.getGeneratedKeys() • Sous MySQL : SELECT LAST_INSERT_ID • Autre SGBD : voir driver propriétaire
  • 13. Récupération de la clé String req=”INSERT …“; st.executeUpdate(sql); // Récupération avec Statement.getGeneratedKeys() rs = st.getGeneratedKeys(); if (rs.next()) cle = rs.getInt(1); // Récupération avec MySQL LAST_INSERT_ID() rs = st.executeQuery("SELECT LAST_INSERT_ID()"); if (rs.next()) cle = rs.getInt(1);
  • 14. Les statement préparés • Permet de faciliter l’écriture de requêtes complexes • Stockées dans le SGBD, seuls les paramètres sont envoyés d’un appel à l’autre • Permet d’éviter divers problèmes de syntaxe... • ...et divers problèmes de sécurité • + quelques bénéfices de performance
  • 15. Exemple de PreparedStatement // Création du Statement PreparedStatement phrase= cnx.prepareStatement(  " INSERT into TABLE (chaine, entier, reel) VALUES (?,?,?) "); 
 // Mise en place des paramètres phrase.setString(1, "uneChaine"); phrase.setInt(2, 56); phrase.setDouble(3, 3.314456); 
 // Exécution de la requête phrase.executeUpdate(); Liste de paramètres
  • 16. Intérêts du PreparedStatement • Légèrement plus efficace (pré-exécution sur le SGBD) • Evite des problèmes de syntaxe • Oublis de ‘ ‘ pour des chaînes,‘ intempestifs • Protège (partiellement) des injections SQL • Insertion illicites de requêtes
  • 17. Traitements batchs Connection connection = ... ; Statement statement = connection.createStatement(); if(connection.getMetaData().supportsBatchUpdates()){ connection.setAutoCommit(false); statement.clearBatch(); //on supprime les anciens batch statement.addBatch("INSERT ...."); statement.addBatch("UPDATE ..."); statement.addBatch("..."); int[] resultat = statement.executeBatch(); //voir les différents types de retour possibles connection.commit(); connection.setAutoCommit(false); }
  • 18. Intégration des accès à la base dans les objets • Un des rôles des objets métiers est de faire la liaison avec la base de données • 3 cas principaux sont à traiter : • Liaison simple une instance = un enreg • Instances encapsulant des listes • Structures hiérarchiques (héritage)
  • 19. Exemple d’intégration d’appels à la base • Une classe User utilisée dans un site Web • On peut : • Se connecter avec un login/mot de passe • A vérifier avec un SELECT • S’enregistrer en donnant un login, un mot de passe, un nom, une adresse... • A concrétiser avec un INSERT INTO...
  • 20. Structure de la classe User • C’est un objet CRUD 
 (Create/Read/Update/Delete) • Exemple de création/ enregistrement :
 User u=new User();
 u.setNom(“.....”);
 ...
 u.insert(); User login password nom select(login,password) insert() update() delete() On verra plus tard qu’il vaut mieux utiliser un pattern DAO
  • 21. Procédure de login • Comment faire à la fois : • Contrôler si un login/pass est correct • Charger les données du user (nom...) • Empêcher qu’une instance de User soit incohérente en mémoire (login/pass incorrect mais encapsulés dans un objet) • Solution : on utilise un constructeur • Avec une lancée d’exception éventuelle
  • 22. Constructeur de User public class User()
 {
 public User(String login, String pwd) 
 throws UserInexistantException()
 {
 String sql=”SELECT nom FROM user
 WHERE login=’”+login+”’ AND pwd=’”+pwd+”’”;
 if(rs.next()) // le login existe
 this.nom=rs.getString(“nom”); // on charge les données
 else // le login n’existe pas
 throw new LoginIncorrectException(login);
 }
  • 23. Exploitation de liaisons 1-N • En objet : c’est un attribut qui contient des instances d’autres objets • En SGBD : c’est le résultat d’une requête avec une clé secondaire • Il va donc falloir faire une requête qui va remplir la liste • Problème : comment instancier chacun des éléments de la liste ?
  • 24. Exemple de liste en objet public class Catalogue { private ArrayList<Produit> liste; public void rech(String texte) { // remplissage de la liste } … } public class Produit { private int cle; private String nom; ... public void load(int cle) { // lecture d’un enregistrement } }
  • 25. Remplissage “procédural” public void rech(String texte) { sql=”SELECT * FROM produit WHERE ...”; while(...) { Produit p=new Produit(); p.setNom(rs.getString(“nom”)); ...
 liste.add(p); } } Problème : on gère la lecture d’un produit en dehors de la classe Produit -> non respect de la notion 
 d’encapsulation
  • 26. Remplissage “objet” public void rech(String texte) { sql=”SELECT cle FROM produit WHERE ...”; while(...) { cle=rs.getInt(“cle”); Produit p=new Produit(); p.load(cle); liste.add(p); } } Problème : On génère un grand nombre de requête (N+1 requêtes, N étant le nombre de produits)
  • 27. Solution mixte public void rech(String texte) { sql=”SELECT * FROM produit WHERE ...”; while(...) { Produit p=new Produit(); p.load(rs); liste.add(p); } } Dans cette solution, on passe à ‘load’ directement le ResultSet “rs” afin de traiter la requête à la source
  • 28. L’héritage dans un modèle relationnel • Problématique : il n’est pas possible de définir directement une structure d’héritage dans un système de tables • Plusieurs solutions sont possibles : • 1 table regroupant tout • 1 table par classe fille • 1 table par classe fille + 1 table pour la classe mère
  • 29. Modèle à une table • A partir d’une hiérarchie de classe Produit -> Cd ou Livre : Table produit : -refprod -type
 -nom -prix -dureecd -nbpageslivres La table contient à la fois les infos du CD, et celles du livre Cette solution est valable si CD et Livre ont peu de données divergentesLe type est encodé dans un champ
  • 30. Une table par classe fille sans factorisation • A partir d’une hiérarchie de classe Produit -> Cd ou Livre : La table Livre contient toutes les données d’un livre Cette solution facilite les requêtes mais complique les recherches inter-catégories Table CD : -refprod -nom -prix -dureecd Table Livre : -refprod -nom -prix -nbpages
  • 31. 1 table par classe fille + 1 table pour classe mère • A partir d’une hiérarchie de classe Produit -> Cd ou Livre : Table Produit : -refprod -type
 -nom -prix La table Livre contient uniquement les données propres au livre Cette solution concilie factorisation et particularité des types de produits Table CD : -refprod -dureecd Table Livre : -refprod -nbpages
  • 32. Lecture base d’une classe polymorphe • On passe par une Factory qui va délivrer suivant les cas une instance de CD, de Livre... Produit p=ProduitFactory.getProduit(int cle); ‘p’ sera en fait une instance de CD, de Livre..
  • 33. Factory modèle à 1 table public static Produit getProduit(int cle) { Produit p=null; sql=”SELECT * FROM produit WHERE ...”; if(...) { type=rs.getString(“type”); if(type.equals(“cd”)) { p=new CD(); p.load(rs); } } return p; }
  • 34. Factory modèle à N tables public static Produit getProduit(int cle) { Produit p=null; p=new CD(); if(!p.load(cle)) { p=new Livre(); if(!p.load(cle)) { ... } else p=null; } return p; } On ne peut que faire des tests en cascade
  • 35. Factory modèle à N tables +1 public static Produit getProduit(int cle) { Produit p=null; sql=”SELECT * FROM produit WHERE ...”; if(...) { type=rs.getString(“type”); if(type.equals(“cd”)) { p=new CD(); p.load(rs); } } return p; } C’est dans chacune des méthodes “load()” que l’on va faire une jointure entre les données ‘mère’ et ‘fille’
  • 36. Conclusion sur ces différents scénarios • Le scénario « 1 table » est peu satisfaisant d’un point de vue SGBD, mais finalement limpide à gérer par la Factory • Le scénario 2 est un peu trop ‘batard’ pour être utile • Le scénario « N tables +1 » est un bon compromis difficulté/propreté de structure • D’autres structures sont envisageables (ex : tables décrivant des listes de champs)
  • 37. Pattern DAO • Data Access Object • Permet de résoudre plusieurs problèmes : • Eviter que les instances d’objets métiers soient trop lourdes en mémoire • Permettre des traitements différenciés suivant les supports (lecture dans un fichier texte, dans un XML, dans une base…) • Séparer la partie métier d’aspects beaucoup plus techniques
  • 38. Implémentation d’un DAO UserDAO<User,Integer> User select(login,password) insert(User) update(User) User login password nom UserMySQLDAO<User,Integer> Connection cnx User select(Integer i) User select(login,password) insert(User) update(User) DAO<T,U> <<abstract>> T select(U id) insert(T) update(T)
  • 39. Utilisation d’un objet DAO User u=new User(); u.setNom(« Leponge »); u.setPrenom(« Bob »); UserDAO dao = new UserMySQLDAO(cnx); dao.insert(u);
  • 41. Rendre un objet persistant • Pour rendre un objet persistant, il suffit de le lier à la session • session.save(objet); • La clé pourra éventuellement être générée automatiquement, et délivrée par save() : • Long cle=(Long)session.save(objet); • (clé déclarée assigned dans le HBM) • Cette clé sera également dans objet.getRef()
  • 42. Sauvegarde par saveOrUpdate • Si la clé a été renseignée dans l’objet : • Si la clé existe en base : UPDATE • Si la clé n’existe pas : INSERT • Si la clé n’a pas été renseignée : INSERT • Si l’objet existe en base et n’a pas été modifié en mémoire : pas de requête générée
  • 43. Chargement d’un objet Client c=(Client)session.load(Client.class,new Long(12)); • ou : Client c=new Client();
 session.load(c,new Long(12)); • version sans lancement d’exception (renvoie null si l’objet n’existe pas) Client c=
 (Client)session.get(Client.class,new Long(12));
 if(c==null)
 c=new Client();
  • 44. Requêtage HQL Query q=session.createQuery(“...”);
 q.setString(0,”..”);
 q.setInt(1,”...”);
 List l=q.list(); // émission de la requête • S’il n’y a qu’un résultat : Client c=(Client)q.uniqueResult();
  • 45. Paramètres d’une requête• Par numéro : FROM Client WHERE nom=? AND age=? q.setString(0,”Dupont”); // commence à 0 • Par nom : FROM Client WHERE nom=:nom AND age=:age q.setString(“nom”,”Dupont”); • Listés : FROM Client WHERE nom IN (:liste) q.setParameterList(“liste”,unTableau);
  • 46. Récupération plusieurs objets d’un coup Query q = sess.createQuery( "SELECT facture,client FROM Facture facture 
 JOIN Client facture.client client");
 List l=q.list();
 Iterator it=l.iterator(); while ( it.hasNext() ) { Object[] tuple = (Object[]) it.next(); Facture f= tuple[0]; Client c = tuple[1]; .... }
  • 47. Association N-1 unidirectionnelle <class name="Item"> <id name="ref" column="refitem"> <generator class="native"/> </id>
 <many-to-one name=”prod” class=”Produit”> <column="refprod" not-null="true"/>
 </many-to-one> </class> <class name="Produit"> <id name="ref" column="refprod"> <generator class="native"/> </id> </class> create table Item ( 
 refitem bigint not null primary key
 refprod bigint not null ) create table Produit ( 
 refprod bigint not null primary key) public class Item ( 
 private Long ref;
 private Produit prod; ) public class Produit ( private Long ref;
 )
  • 48. Association 1-1 unidirectionnelle <class name="Client"> <id name="ref" column="refcli"> <generator class="native"/> </id>
 <many-to-one name=”panier” class=”Panier”> <column="refpanier"
 unique=”true” not-null="true"/>
 </many-to-one> </class> <class name="Panier"> <id name="ref" column="refpanier"> <generator class="native"/> </id> </class> create table Client ( 
 refcli bigint not null primary key
 refpanier bigint not null ) create table Panier ( 
 refpanier bigint not null primary key) public class Client ( 
 private Long ref;
 private Panier panier; ) public class Panier ( private Long ref;
 )
  • 49. Association 1-N unidirectionnelle <class name="Client"> <id name="ref" column="refclient"> <generator class="native"/> </id> <set name="factures"> <key column="refclient" not-null="true"/> <one-to-many class="Facture"/> </set> </class> <class name="Facture"> <id name="ref" column="reffacture"> <generator class="native"/> </id> </class> create table Client ( 
 refclient bigint not null primary key ) create table Facture ( 
 reffacture bigint not null primary key,
 refclient bigint not null ) public class Client ( 
 private Long ref;
 private List factures; ) public class Facture ( private Long ref;
 )
  • 50. Représentation d’héritage avec une table <class name="Produit" table="produit" abstract=”true” discriminator-value=”-”> <id name="ref" column="ref"> <generator class="native"/> </id> <discriminator column="type" type="character"/> <property name="titre"/> 
 <subclass name="Livre" discriminator-value="L"> <property name="nbpages"/> </subclass> <subclass name="CD" discriminator-value="C"> <property name="duree"/> <property name="maisondisque"/> </subclass> </class> create table produit ( ref BIGINT not null, type CHAR(1) not null, titre VARCHAR(255), duree FLOAT, maisondisque VARCHAR(255), nbpages INTEGER, primary key (ref) )
  • 51. Représentation d’héritage avec plusieurs tables <class name="Produit" table="produit" abstract=”true”> <id name="ref" column="refprod"> <generator class="native"/> </id> <discriminator column="type" type="character"/> <property name="titre"/> 
 <join-subclass name="CD" table="cd"> <key column="refprod"/> <property name="maisondisque"/> </subclass> </class> create table produit ( ref BIGINT not null, type CHAR(1) not null, titre VARCHAR(255), duree FLOAT, maisondisque VARCHAR(255), nbpages INTEGER, primary key (ref) ) create table cd ( ref BIGINT not null, maisondisque VARCHAR(255), primary key (ref) )