Quelques patterns pour la persistance des objets avec DAO

Page 1 sur 13Lecteur de document UniversityLib

Quelques patterns pour la persistance des objets avec DAO

Software Engineering · course

Voir tous les documents en génie logiciel

Quelques patterns

pour la persistance des objets

avec DAO

Université de Nice Sophia-Antipolis

Version 1.4 – 30/8/07

Richard Grin

(cid:137) Ce cours présente des modèles de

conception utilisés pour effectuer la

persistance des objets

R. Grin

Mapping objet-relationnel

page 2

Principe de base

(cid:137) Il est plus fréquent de changer la façon

d’effectuer la persistance que de changer le

modèle « métier »

(cid:137) Pour faciliter les changements dans la

persistance il faut isoler le plus possible le

code qui gère la persistance

DAO

(cid:137) La persistance est isolée dans des objets

spécifiques, les DAO (Data Access Objects)

R. Grin

Mapping objet-relationnel

page 3

R. Grin

Mapping objet-relationnel

page 4

Le modèle de conception DTO

(Data Transfer Object)

Utilité des DTOs

(cid:137) Les DAOs sont situés dans une couche

proche de la base de données

(cid:137) Le code utilisateur des DAOs est souvent

situé sur une autre couche distante

(cid:137) Les DTOs peuvent être utilisés pour

transporter les données entre les différentes

couches distantes

R. Grin

Mapping objet-relationnel

page 5

R. Grin

Mapping objet-relationnel

page 6

1

Un fait important

Le problème à résoudre

(cid:137) Les appels de méthode distants sont

beaucoup plus coûteux que les appels locaux

(cid:137) Le coût dépend peu de la quantité de

données transférée à chaque appel

(cid:137) Un client souhaite récupérer des données en

interrogeant des objets distants non

facilement transportables sur le réseau

(cid:137) Exemple : récupérer les nom, prénom, salaire

et lieu de travail d’un employé

(cid:137) S’il utilise les accesseurs des classes des

objets (getNom, getPrenom, getSalaire,

getLieu), plusieurs appels distants sont

nécessaires

R. Grin

Mapping objet-relationnel

page 7

R. Grin

Mapping objet-relationnel

page 8

La solution DTO

(cid:137) Le client demande un objet qui contient

toutes les valeurs dont il a besoin

(cid:137) Cet objet, un Data Transfert Object (DTO),

est construit sur le site distant et passé en

une seule fois au client

(cid:137) Un DTO contient l’état d’un ou de plusieurs

objets métier, mais pas leur comportement

(cid:137) Synonyme : Transfert Object (TO)

Exemples d’utilisation des DTO

(cid:137) Transporter les données d’un objet distant

pas transportable sur le réseau (pas

sérialisable)

(cid:137) Transporter plusieurs objets distants en un

seul appel distant ; par exemple une facture

avec toutes les lignes de facture et les

informations sur les produits

(cid:137) Pour éviter les complications inutiles il faut

éviter les DTOs si l’application est locale (pas

distribuée)

R. Grin

Mapping objet-relationnel

page 9

R. Grin

Mapping objet-relationnel

page 10

DTO pour modifier

(cid:137) Un DTO peut aussi être utilisé, plus

généralement pour modifier un ou plusieurs

objets distants (ou les données de la base de

données) :

n le DTO est créé ou modifié sur une couche

de l’application

n il est passé à une couche distante qui

utilise ses données pour modifier un ou

plusieurs objets distants (ou la base de

données)

Le modèle de conception DAO

(Data Access Object)

R. Grin

Mapping objet-relationnel

page 11

R. Grin

Mapping objet-relationnel

page 12

2

Le problème à résoudre

La solution

(cid:137) Le code pour la persistance varie beaucoup

n avec le type de stockage (BD relationnelles,

BD objet, fichiers simples, etc.)

n avec les implémentations des fournisseurs

de SGBD

(cid:137) Si les ordres de persistance sont imbriqués

avec le code « métier », il est difficile de

changer de source de données

(cid:137) Encapsuler le code lié à la persistance des

données dans des objets DAO dont l’interface est

indépendante du support de la persistance

(cid:137) Le reste de l’application utilise les DAOs pour

gérer la persistance, en utilisant des interfaces

abstraites, indépendantes du support de

persistance ; par exemple,

Employe getEmploye(int matricule)

R. Grin

Mapping objet-relationnel

page 13

R. Grin

Mapping objet-relationnel

page 14

DAO

Utilité des DAOs

(cid:137) Quand l’application a besoin d’effectuer une

opération liée à la persistance d’un objet, elle

fait appel à un objet DAO à qui elle passe les

informations nécessaires pour effectuer

l’opération

(cid:137) Chaque classe d’objet métier a son propre type

de DAO (DAOEmploye, DAODepartement, …)

(cid:137) Mais le même objet DAO peut être utilisé pour

tous les objets d’une classe d’objet métier

(cid:137) Plus facile de modifier le code qui gère la

persistance (changement de SGBD ou même

de modèle de données)

(cid:137) Factorise le code d’accès à la base de données

(cid:137) Plus facile pour le spécialiste des BD

d’optimiser les accès (ils n’ont pas à parcourir

toute l’application pour examiner les ordres

SQL)

(cid:137) Sans doute le modèle de conception le plus

utilisé dans le monde de la persistance

R. Grin

Mapping objet-relationnel

page 15

R. Grin

Mapping objet-relationnel

page 16

Emplacement des DAOs

CRUD

(cid:137) Les DAOs sont placés dans la couche dite

« d’accès aux données » qui est souvent sur

une autre machine que la couche des objets

métiers

(cid:137) Les échanges de messages entre les DAOs

et les objets métiers engendrent donc

souvent des appels distants et des DTO

peuvent donc être utilisés pour améliorer la

vitesse des échanges

(cid:137) Cet acronyme désigne les opérations de base de

la persistance : create, retrieve, update et delete

(cid:137) Ces 4 opérations de base sont implémentées

dans un DAO

R. Grin

Mapping objet-relationnel

page 17

R. Grin

Mapping objet-relationnel

Publicité

page 18

3

CRUD

(cid:137) Create pour créer une nouvelle entité dans la

base

(cid:137) Retrieve pour retrouver une ou plusieurs

entités de la base

(cid:137) Update pour modifier une entités de la base

(cid:137) Delete pour supprimer une entité de la base

(cid:137) Plusieurs variantes pour les signatures de

ces méthodes dans les DAOs

create - paramètres

(cid:137) Prend en paramètre l’état de la nouvelle entité

(cid:137) Cet état peut être donné

n par une série de paramètres des types des

données : create(int id, String nom,…)

n par un DTO : create(DTOxxx dto)

n par l’objet métier que l’on veut rendre

persistant : create(Article article)

R. Grin

Mapping objet-relationnel

page 19

R. Grin

Mapping objet-relationnel

page 20

create – type retour

create – comparaison des variantes

(cid:137) Le type retour peut être

n void (la variante la plus utilisée)

n boolean pour indiquer si la création a pu

avoir lieu (on peut utiliser une exception à la

place)

n l’identificateur de l’entité ajoutée (utile si la

clé primaire est générée automatiquement

dans la base de données)

n un objet métier ou un DTO correspondant à

l’entité ajoutée

(cid:137) Les variantes qui passent les différentes

valeurs individuellement sont les plus souples

(cid:137) Lorsque les DTOs sont utilisées par ailleurs,

les variantes avec DTO sont souvent

rencontrées

(cid:137) Les variantes avec objet métier ne conviennent

que si l’objet métier a toutes ses propriétés

publiques et s’il est facilement transportable

(cid:137) Mais elle peut être pratique et performante

dans les cas où elle sont applicables

R. Grin

Mapping objet-relationnel

page 21

R. Grin

Mapping objet-relationnel

page 22

Exemple de code JDBC pour create

private String insert =

"insert into STYLO (ref, nom, prix, couleur)

variable d’instance

values(?, ?, ?, ?)";

...

PreparedStatement ps =

méthode create

connexion.prepareStatement(insert);

ps.setString(1, reference);

ps.setString(2, nom);

ps.setString(3, couleur);

ps.setBigDecimal(4, prix);

ps.executeUpdate();

retrieve

(cid:137) 3 types de méthode, suivant qu’elle retourne

n un seul objet

n une collection d’objets

n une valeur calculée à partir de plusieurs

entités (agrégation)

(cid:137) Une méthode (ou un objet) qui retourne des

données de la base de données est souvent

appelée finder

R. Grin

Mapping objet-relationnel

page 23

R. Grin

Mapping objet-relationnel

page 24

4

Exemples de finders

Finderqui retourne un objet

(cid:137) On trouvera le plus souvent

n une méthode findById(id) (ou d’un

nom semblable…) qui retrouve une entité

en donnant son identificateur dans la base

n une méthode findAll() qui retrouve

toutes les entités du type géré par le DAO

(cid:137) Mais on trouvera aussi des finders qui

cherchent suivant des critères quelconques

ou suivant des critères bien précis (ces

finders dépendent des traitements métier)

(cid:137) On lui passe en paramètre un identificateur

de l’entité cherchée

(cid:137) Il retourne un objet métier qui correspond à

l’entité cherchée, ou un DTO qui contient les

données de l’entité cherchée

(cid:137) Si le finder retourne un objet unique, il

retourne null si rien n’a été trouvé

R. Grin

Mapping objet-relationnel

page 25

R. Grin

Mapping objet-relationnel

page 26

Finderqui retourne une collection

(cid:137) On lui passe en paramètre le critère de

sélection, sous une forme quelconque

n objet ou valeurs « critère de sélection »

n objet « exemple » (à la « query by

example »)

(cid:137) Le type retour peut être très divers :

n ResultSet

n RowSet

n Collection (Collection, List, Set,…)

d’objets métier ou de DTOs

n tableau (rare)

Résultat vide

(cid:137) Si le critère de la requête n’est vérifiée par

aucune valeur, le finder doit retourner une

« collection » (collection, resultset rowset ou

tableau) vide

(cid:137) Retourner la valeur null obligerait à un cas

particulier pour le traitement de la valeur

retournée (« if (result == null) » avant une

boucle qui parcourt le résultat)

R. Grin

Mapping objet-relationnel

page 27

R. Grin

Mapping objet-relationnel

page 28

Finderqui retourne

une valeur calculée

(cid:137) Les valeurs calculées à partir des données

de plusieurs entités (exemple : total des

salaires) peuvent s’obtenir à partir d’objets

chargés en mémoire

(cid:137) Mais il peut être préférable de ne pas créer

les objets et d’interroger directement la base

de données qui est optimisée pour ce type de

requête

(cid:137) Un DAO peut ainsi comporter une méthode

qui renvoie le total des salaires des employés

update

(cid:137) Des variantes diverses pour les paramètres :

n identificateur + valeurs (plusieurs

paramètres pour les valeurs ou un seul

DTO)

n l’objet métier dont on veut sauvegarder les

modifications (nécessite un accès public

aux valeurs qui seront modifiées)

(cid:137) Le type retour peut être

n void

n boolean pour indiquer si la modification a

pu avoir lieu

R. Grin

Mapping objet-relationnel

page 29

R. Grin

Mapping objet-relationnel

page 30

5

delete

Autres méthodes des DAOs

(cid:137) Variantes pour les paramètres :

n identificateur de l’entité à supprimer dans

la base

n l’objet métier (ou un DTO) correspondant à

l’entité à supprimer dans la base

(cid:137) Variantes pour le type retour :

n void

n boolean pour indiquer si la suppression a

pu avoir lieu

(cid:137) Outre les opérations CRUD, les DAO peuvent

aussi implémenter des méthodes spécifiques

au modèle métier de l’application

(cid:137) Le plus souvent ce sont des variantes de

l’opération « retrieve »

(cid:137) Par exemple une méthode qui renvoie les

Publicité

candidats qui ont une mention à un examen

R. Grin

Mapping objet-relationnel

page 31

R. Grin

Mapping objet-relationnel

page 32

2 stratégies d’utilisation des DAOs

Stratégie 1

1. Chaque objet métier a une référence à son

DAO et l’utilise pour sa propre persistance.

Le programme qui manipule les objets

métier ne connaît pas les DAOs

2. Le programme qui manipule les objets

métier utilise directement les DAOs.

Les objets métier n’ont pas de référence à

un DAO (stratégie sans doute la plus

fréquemment utilisée)

(cid:137) Les programmes qui manipulent les objets

métier ne sont pas modifiés par rapport à un

programme qui n’utilise pas de DAO

(cid:137) Seuls les objets métier connaissent leur DAO

(cid:137) Les objets métier doivent avoir une référence

vers le DAO qu’ils utilisent

(cid:137) Cette référence peut être obtenue par une

méthode static de la classe DAO (ce qui

peut permettre de partager un DAO entre tous

les objets métier d’une même classe)

R. Grin

Mapping objet-relationnel

page 33

R. Grin

Mapping objet-relationnel

page 34

Exemple de code

class Stylo {

private StyloDAO dao;

...

public void sauvegardeToi() {

dao = getDAO();

dao.insertOrUpdate(this);

}

private StyloDAO getDAO() {

on peut aussi

construire un

DTO pour le

passer au DAO

Stratégie 2

(cid:137) On rencontre le plus souvent la stratégie 2

(cid:137) On perd sans doute de la pureté de la

programmation objet

if (dao == null)

StyloDAO.getDAO();

return dao;

Pour simplifier, on ne

tient pas compte des

exceptions

Mapping objet-relationnel

page 35

R. Grin

Mapping objet-relationnel

page 36

}

R. Grin

6

Exemple de code

Exemple de code (variante)

// ou styloDAO = new StyloDAO()

StyloDAO styloDAO = StyloDAO.getDAO();

int idStylo =

styloDAO.create("Marker", "noir ",

DTO ou objet

métier

120,...);

. . .

Stylo stylo = styloDAO.findById(idStylo);

styloDAO.update(idStylo, ...);

List<Stylo> l = styloDAO.findAll();

Nouvelles

valeurs pour

le stylo

// ou styloDAO = new StyloDAO()

StyloDAO styloDAO = StyloDAO.getDAO();

styloDAO.create(145, "Marker",

"noir ", 120,...);

. . .

Stylo stylo = styloDAO.findById(1234);

stylo.setPrix(45);

styloDAO.update(stylo);

List<Stylo> l = styloDAO.findAll();

R. Grin

Mapping objet-relationnel

page 37

R. Grin

Mapping objet-relationnel

page 38

Diagramme de classes (avec

utilisation de TO)

Diagramme de séquences

Cette image (et les suivantes) sont extraites du

« Core J2EE Pattern Catalog » de Sun

R. Grin

Mapping objet-relationnel

page 39

Modification de plusieurs attributs persistants en utilisant un DTO :

création du DAO, puis récupération des valeurs actuelles,

puis modification de ces valeurs

R. Grin

Mapping objet-relationnel

page 40

Problèmes avancés sur les DAO

Problèmes abordés

(cid:137) DAO et exceptions

(cid:137) DAO et connexions

(cid:137) DAO et transactions

(cid:137) DAO et objets composés

(cid:137) DAO et héritage

R. Grin

Mapping objet-relationnel

page 41

R. Grin

Mapping objet-relationnel

page 42

7

DAO et exceptions (1)

DAO et exceptions (2)

(cid:137) Les méthodes des DAO peuvent lancer des

exceptions puisqu’elles effectuent des

opérations d’entrées-sorties

(cid:137) Les exceptions ne doivent pas être liées à un

type de DAO particulier si on veut pouvoir

changer facilement de type de DAO

(cid:137) Pour cela, on crée une ou plusieurs classes

d’exception indépendantes du support de

persistance, désignons-les par DAException

(ou DataAccessException ou

DaoException)

(cid:137) Les méthodes des DAO attrapent les exceptions

particulières, par exemple les SQLException,

et relancent des DAException (auxquels sont

chaînées les exceptions d’origine pour faciliter la

mise au point)

R. Grin

Mapping objet-relationnel

page 43

R. Grin

Mapping objet-relationnel

page 44

DAO et connexions (1)

DAO et connexions (2)

(cid:137) Une connexion peut être ouverte au début

des méthodes du DAO, et fermée à la fin des

méthodes

(cid:137) Il est préférable que les connexions soient

ouvertes par les clients du DAO

(cid:137) En ce cas, les connexions ouvertes doivent

(cid:137) Cette stratégie va coûter cher si un pool de

être passées au DAO

connexions n’est pas utilisé

(cid:137) Pour cela le DAO peut comporter une

méthode setConnection(Connection c)

(la façon de faire dépend de l’API de

persistance que l’on utilise ; avec JPA on

passera le manager d’entité et avec

Hibernate la session)

R. Grin

Mapping objet-relationnel

page 45

R. Grin

Mapping objet-relationnel

page 46

Qui gère les transactions ?

Transactions gérées par les clients

(cid:137) Un DAO pourrait démarrer et terminer lui-

même les transactions à chaque méthode

(cid:137) Cependant il n’est pas rare de vouloir inclure

un ou plusieurs appels de méthodes de

DAOs dans une seule transaction

(cid:137) L’implémentation des DAOs doit donc

permettre cette dernière possibilité : ce sont

les clients du DAO qui vont gérer les

transactions

(cid:137) C’est le client du DAO, et pas le DAO qui va

Publicité

indiquer quand une transaction doit être

validée ou invalidée

(cid:137) Le DAO utilise la transaction en cours si elle

existe

R. Grin

Mapping objet-relationnel

page 47

R. Grin

Mapping objet-relationnel

page 48

8

Exemple schématique JDBC - DAO

public class StyloDao {

private Connection conn;

public void setConnection(Connection c) {

this.conn = c;

}

public long create(...) {

PreparedStatement pstmt =

conn.prepareStatement(...);

pstmt.setString(...);

...

pstmt.executeUpdate();

Exemple schématique JDBC - client

Connection conn = ... ;

daoStylo.setConnection(conn);

daoRamette.setConnection(conn);

...

daoStylo.create(...);

daoFacture.update(...);

conn.commit();

}

R. Grin

Mapping objet-relationnel

page 49

R. Grin

Mapping objet-relationnel

page 50

Tout n’est pas parfait !

Solution partielle

(cid:137) On vient de voir qu’avec un DAO JDBC, il faut

passer une connexion ; avec un DAO JPA

(étudié dans une autre partie du cours) il faut

passer un gestionnaire d’entités

(cid:137) Il est donc difficile de rendre l’utilisation des

DAOs totalement indépendante du type de

persistance si on veut gérer des types de

persistance très différents

(cid:137) Malgré tout, l’utilisation des DAOs diminue

fortement la dépendance vis-à-vis des types de

persistance

(cid:137) Par exemple, pour la gestion des

transactions, le code différent concernera

l’initialisation des DAOs (avec une connexion

ou avec un autre objet)

(cid:137) La solution est de ne pas mettre la méthode

setConnection dans l’interface du DAO et

de caster le DAO dans un type concret, le

temps de l’initialiser

R. Grin

Mapping objet-relationnel

page 51

R. Grin

Mapping objet-relationnel

page 52

DAO et objets composés

(cid:137) Par exemple, pour une facture, la question

doit être posée : le dao pour les factures doit-

il retourner les lignes de la facture ?

(cid:137) Il n’y a pas de réponse générale ; la réponse

dépend du contexte

Le modèle de conception

« fabrique abstraite »

R. Grin

Mapping objet-relationnel

page 53

R. Grin

Mapping objet-relationnel

page 54

9

Un cas d’utilisation

Avec un constructeur

(cid:137) Une application fonctionne sur un ordinateur

portable

(cid:137) Une application peut utiliser une base locale

MySQL si l’ordinateur n’est pas connecté à

Internet, ou une base Oracle distante s’il est

connecté

(cid:137) Comment utiliser le bon DAO pour chaque

classe métier (par exemple, utiliser un

DAOStyloMySQL ou un DAOStyloOracle

suivant le cas) ?

(cid:137) Le code

DaoStylo dao = new DaoStyloOracle();

fixe le type de DAO créé

(cid:137) Il devra être modifié si on veut un autre type

R. Grin

Mapping objet-relationnel

page 55

R. Grin

Mapping objet-relationnel

page 56

Pattern « fabrique »

pour récupérer les DAO

(cid:137) Le pattern « fabrique » (factory) permet de

créer des instances en cachant le type

concret des instances créées

Avec une fabrique

(cid:137) DaoStylo dao =

fabriqueDaoStylo.getDao();

(cid:137) dao sera du type DaoStyloOracle ou

DaoStyloMySQL selon le cas

(cid:137) DaoStylo est une interface implémentée par

les classes concrètes de DAO

DaoStyloOracle et DaoStyloMySQL

(cid:137) Signature de getDao() :

DaoStylo getDao()

R. Grin

Mapping objet-relationnel

page 57

R. Grin

Mapping objet-relationnel

page 58

Avec une fabrique

(cid:137) Pour fixer le type renvoyé, il suffit de

l’indiquer auparavant à la fabrique par le code

fabriqueDaoStylo

.setTypeDao(typeDao);

(cid:137) typeDao peut, par exemple, être déterminé

en testant si l’ordinateur est connecté ou non

à Internet

Fabrique abstraite

(cid:137) Si on veut changer de base de données, le

type de DAO doit être fixé pour toutes les

fabriques de DAOs

(cid:137) Le pattern « fabrique abstraite » permet de

changer plus facilement de base de données

(cid:137) En une seule ligne de code tous les DAOs

peuvent être remplacés par des DAOs

adaptés à la nouvelle base de données

choisie

R. Grin

Mapping objet-relationnel

page 59

R. Grin

Mapping objet-relationnel

page 60

10

Fabrique abstraite

(cid:137) Une fabrique abstraite est un type abstrait qui

permet de cacher les types réels d’un

ensemble de fabriques concrètes

(cid:137) Chaque fabrique concrète fournit tous les

DAOs (DAOStylo, DAORamette,…)

associés à une certaine source de données

(cid:137) Dans la ligne de code, on récupère la bonne

fabrique de DAOs, associée à la bonne

source de données

R. Grin

Mapping objet-relationnel

page 61

Code pour fabrique abstraite

(cid:137) Le code qui suit est un exemple schématique

de l’utilisation du pattern DAO, avec le pattern

fabrique abstraite (inspiré fortement d’un

exemple donné par Sun)

(cid:137) Il utilise le pattern DTO/TO exposé dans la

1ère partie de ce cours

(cid:137) Ce pattern DTO peut être évité si les objets

persistants peuvent être transportés entre les

différentes couches d’une application (par

exemple, pour une application locale, ou en

utilisant les objets « détachés » de JPA ou de

Hibernate)

Mapping objet-relationnel

page 62

R. Grin

Le type

abstrait

Code client (début)

DAOFactory daoFactory =

DAOFactory.getDAOFactory(

La seule ligne de code

Publicité

pour changer de

SGBD

DAOFactory.TypeDao.MYSQL);

styloDAO = daoFactory.getStyloDAO();

// crée un nouveau stylo dans la base

int styloNo = styloDAO.create(...);

// Trouve un stylo

StyloTO styloTO = styloDAO.find(...);

// Modifie des valeurs du DTO

styloTO.setPrix(125);

// Modifie le stylo dans la base

styloDAO.update(styloTO);

Code client (suite)

// Supprime un stylo de la base

styloDAO.delete(styloNo);

// Trouve tous les stylos d’une marque

// Utilise un stylo « exemple » de ce

// que l’on cherche

StyloTO styloEx = new StyloTO();

styloEx.setMarque("Marker");

Collection<StyloTO> listeStylos =

styloDAO.find(styloEx);

...

R. Grin

Mapping objet-relationnel

page 63

R. Grin

Mapping objet-relationnel

page 64

Fabrique abstraite – 1 DAO

Fabrique abstraite – 1 source de données

La fabrique

abstraite

Les fabriques

concrètes

Les DAOs

créés

Une fabrique concrète

crée tous les DAOs

associés à une source

de données

R. Grin

Mapping objet-relationnel

page 65

R. Grin

Mapping objet-relationnel

page 66

11

Fabrique abstraite – schéma global

Code pour fabrique abstraite

(cid:137) Le code qui suit est un exemple schématique

de l’utilisation du pattern DAO, avec le pattern

fabrique abstraite (inspiré fortement d’un

exemple donné par Sun)

(cid:137) Il utilise aussi le pattern DTO/TO

(cid:137) Important : ce pattern DTO peut être évité si

les objets persistants peuvent être

transportés entre les différentes couches

d’une application (par exemple, pour une

application locale, ou en utilisant les objets

« détachés » de JPA ou de Hibernate)

R. Grin

Mapping objet-relationnel

page 67

R. Grin

Mapping objet-relationnel

page 68

La fabrique abstraite

Une fabrique concrète

public abstract class DAOFactory {

public enum TypeFabrique {MYSQL, ORACLE};

public abstract StyloDAO getStyloDAO();

public abstract FactureDAO getFactureDAO();

...

public static DAOFactory getDAOFactory(

TypeFabrique typeFabrique) {

switch (typeFabrique) {

case MYSQL: return new MysqlDAOFactory();

case ORACLE: return new OracleDAOFactory();

default: ... ; // erreur

}

}

}

R. Grin

Mapping objet-relationnel

page 69

public class MySQLDAOFactory

extends DAOFactory {

@Override

public StyloDAO getStyloDAO() {

return new MySQLStyloDAO();

}

@Override

public FactureDAO getFactureDAO() {

return new MySQLFactureDAO(); }

...

}

R. Grin

Mapping objet-relationnel

page 70

Interface des DAO pour Stylo

DAO concret pour Stylo

public interface StyloDAO {

public int insert(...);

public boolean delete(...);

public StyloDTO find(...);

public boolean update(...);

public Collection<StyloTO> findAll(...);

public Collection<StyloTO> find(...);

...

référence

}

objet exemple

R. Grin

Mapping objet-relationnel

page 71

import java.sql.*;

public class MySQLStyloDAO

implements StyloDAO {

public MySQLStyloDAO() { ... }

public int insert(…) { ... }

public boolean delete(…) { ... }

public StyloTO find(…) { ... }

public boolean update(...);

public Collection<StyloTO> findAll(...);

...

}

R. Grin

Mapping objet-relationnel

page 72

12

TO pour Stylo

Inconvénient de ce pattern

import java.io.Serializable;

public class StyloTO implements Serializable {

private String reference;

private String name;

...

// Accesseurs et modificateurs

public String getReference() {...}

public void setReference(String ref) {...}

...

indispensable pour être

transporté d’une couche

à une autre

}

(cid:137) Si on veut ajouter un nouveau type de DAO

(par exemple, un DAO pour un autre article),

il faut modifier le code de toutes les fabriques

abstraite et concrètes

R. Grin

Mapping objet-relationnel

page 73

R. Grin

Mapping objet-relationnel

page 74

DAO et EJB

Bibliographie

(cid:137) Dans les applications construites selon la

spécification EJB, les DAOs seront le plus

souvent des beans sessions sans état

(@Stateless) avec des contextes de

persistance limités à une transaction (voir

cours sur JPA)

(cid:137) Patterns of Entreprise Application

Architecture de Martin Fowler – Addison

Wesley

(cid:137) Présentation du pattern DAO et

implémentation en Java, par Sun :

http://java.sun.com/blueprints/corej2eepattern

s/Patterns/DataAccessObject.html

R. Grin

Mapping objet-relationnel

page 75

R. Grin

Mapping objet-relationnel

page 76

13