IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[Conception] DAO, CRUD ou SRD ?


Sujet :

Java

  1. #1
    Invité
    Invité(e)
    Par défaut [Conception] DAO, CRUD ou SRD ?
    Bonjour,

    Juste une petite question, dans la littérateure on retrouve très souvent le terme CRUD (Create Retrieve Update Delete) lorsque l'on parle de DAO.
    Or il y à deux actions que l'on pourrais regrouper : Create et Update. Dans tous les logiciels existants, on ne vous propose pas de sauver un nouveau projet et de mettre à jour un projet, juste de le sauver.

    Pourquoi ne pas proposer la même logique aux|à l'utilisateur du DOA (Save Retrieve, Delete) ?
    Comme presque tout ce qui est sauvé utilise un identifiant unique, on pourrais très bien se baser sur cette valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    public class MyBean {
      private int id;
     
      public MyBean() {
        this.id=-1;
      }
    }
     
    public class MyBeanDaoImpl implements MyBeanDao {
     
      public int save(MyBean myBean) {
        if ( myBean.getId()<0 ) {
          // INSERT INTO...
        } else {
          // UPDATE
        }
      }
    }
    Je ne vois pas trop d'inconvénient à cette méthode. Donc, pourquoi parle t'on toujours de CRUD et pas de SRD (Save, Reptrieve, Delete) ?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Citation Envoyé par Blaise1 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public class MyBeanDaoImpl implements MyBeanDao {
     
      public int save(MyBean myBean) {
        if ( myBean.getId()<0 ) {
          // INSERT INTO...
        } else {
          // UPDATE
        }
      }
    }
    Je ne vois pas trop d'inconvénient à cette méthode. Donc, pourquoi parle t'on toujours de CRUD et pas de SRD (Save, Reptrieve, Delete) ?
    Bah, tout simplement parce que create et update sont deux opérations différentes. D'ailleurs sur les logiciels desktop, en général on propose Enregistrer et Enregistrer sous.... Création pour quelque chose qui n'existe pas encore en stockage persistent et Update pour quelque chose qui existe déjà. D'ailleurs Hibernate propose une méthode session.saveOrUpdate() qui en gros fait la même chose que ta méthode ci-dessus. Mais je pense que la distinction est surtout nécessaire d'un point de vue de l'utilisateur qui doit bien savoir ce qu'il fait, une création ou une mise à jour, et peu importe comment tu fais ton implémentation derrière.

  3. #3
    Invité
    Invité(e)
    Par défaut Et pour la récupération ?
    Citation Envoyé par manblaizo Voir le message
    Mais je pense que la distinction est surtout nécessaire d'un point de vue de l'utilisateur qui doit bien savoir ce qu'il fait, une création ou une mise à jour, et peu importe comment tu fais ton implémentation derrière.
    Oui c'est sur qu'il doit savoir ce qu'il fait mais pour les développeurs c'est plus imple d'utiliser "MyBeanDao.save(myBean)".. Enfin en même temps faire "if (myBean.getId()<0)" dans le métier ou dans le dao c'est vrai que ça ne change pas grand chose (de toutes façons dans le dao j'aurais crée deux méthodes privées "insertMyBean" et "updateMyBean")
    Ok donc.


    Mais maintenant pour la récupération, je suppose qu'il est préférable d'écrire
    une méthode "findMyBean(int beanId)" et une méthode "findMyBean(...)" ? Mais que mettre comme paramètres dans cette dernière ? Une instance de MyBean qui me sers de pattern ou une clause WHERE valide SQL ?

  4. #4
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Bonjour.
    if (myBean.getId()<0)
    A mon avis, ce bout de code est dangereux: il suffit d'oublier d'initialiser l'id dans le constructeur à une vleur négative pour que ça pète. Bref, le meiux serait de n apas faire de présomptions sue les valeurs des identifiants car ça varie beaucoup de SGBD à un autre et d'une stratégie de génération d'id à une autre.

    Personellement, je pase par une id de type Object (Long, Integer, etc.) et je compare avec null, ce qui est plus sur.

    Une instance de MyBean qui me sers de pattern ou une clause WHERE valide SQL ?
    Surtout pas la deuxième ... je peux te citer plein de problèmes avec ça:
    - pas super portable entre SGBDs.
    - pas de séparation de taches: qui va générer du SQL qui sera passé au DAO qui est censé faire l'abstraction du SQL ?
    - tu t'exposes à l'SQL injection.
    - etc.

    La première approche peut être intéressante uniquement lorsque l'on utilise un ORM qui la supporte (comme Hibernate et les Criteria).

    Bonne chance.

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Surtout pas la deuxième ... je peux te citer plein de problèmes avec ça:
    - pas super portable entre SGBDs.
    - pas de séparation de taches: qui va générer du SQL qui sera passé au DAO qui est censé faire l'abstraction du SQL ?
    - tu t'exposes à l'SQL injection.
    - etc.
    Pas vraiment d'accord avec ça... ou alors ça dépend de la façon de faire...
    Personnellement, je préfère avoir des méthodes avec les arguments de "filtrage" fournis :
    (méthode avec EJB3)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public List<Person> findPerson(String nom, String prenom)
    {
       StringBuilder sb = new StringBuilder();
       sb.append("select p from Person p where 1=1");
     
       if ( isParameterSet(nom) ) sb.append(" and nom like :nom");
       if ( isParameterSet(prenom) ) sb.append(" and prenom like :prenom");
     
       Query query = entityManager.createQuery(sb.toString());
     
       if ( sb.indexOf(":nom") != -1 ) query.setParameter("nom", nom);
       if ( sb.indexOf(":prenom") != -1 ) query.setParameter("prenom", prenom);
     
       return query.getResultList();
    }
    - Pas de risque d'injection SQL
    - Portable
    - Complètement dédié à la facade
    - Facile à comprendre
    etc...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Je parlais en fait de ceci:
    Citation Envoyé par Blaise1
    ou une clause WHERE valide SQL ?

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Surtout pas la deuxième ... je peux te citer plein de problèmes avec ça:
    - pas super portable entre SGBDs.
    - pas de séparation de taches: qui va générer du SQL qui sera passé au DAO qui est censé faire l'abstraction du SQL ?
    - tu t'exposes à l'SQL injection.
    - etc.
    - Ben quand même un WHERE c'est assez portable non ? Je ne connais pas tous les SGBD mais Mysql, Postgres, Oracle, Foxpro(ou truc du style), Hsql et même Access connaissant el WHERE et la synatxe est la même.
    - On peux voir le bout de code SQL comme une abstraction. Le développeur se fout du support, il veux les MyBean dont le nom comprend test -> WHERE nom LIKE '%test%', il y à bien l'EJBQL, je partais sur le même principe mais sans créer un pseudo langage de plus
    - Les daos seront utilisés par d'autres développeurs, si ils veulent faire une injection qui drop la db c'est leur problème..


    La méthode en utilisant un pattern je l'ai déjà mise en application mais c'est assez lourd à coder car il fallait prendre tous les attributs en compte.


    Je n'ai pas non plus envie de limiter les critères de recherche, on ne sais jamais de quoi le future sera fait, j'étais arrivé à une méthode de ce style "public List<MyBean> findMyBean(String... criterias) throws TrucMuchException;" ?
    Dernière modification par Invité ; 16/11/2007 à 17h23.

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Là ou je rejoins complètement djo.mos, c'est sur la clause where passée en paramètre, gros risque d'injection...
    Tu peux imaginer plusieurs mécaniques de passage d'arguments, soit comme je le proposais avec les paramètres nommés, soit par une Map (nom propriété, valeur de comparaison) ce qui évitera la modification des références mais rendra le code moins lisible...
    L'utilisation d'un objet modèle me parait moins portable, donc, à éviter...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Là ou je rejoins complètement djo.mos, c'est sur la clause where passée en paramètre, gros risque d'injection...
    Je ne comptais pas passer de clause WHERE complète. Juste des égalités devant êtres vérifiées :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public interface MyBeanDAO {
     
      List<MyBean> findMyBean(String... args);
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class MyBeanDAOImpl implements MyBeanDAO {
     
      List<MyBean> findMyBean(String... args) {
        StringBuffer clauses = new StringBuffer();
        for ( inti=0; i<args.length; i++) {
          clauses.append(args[i]);
          if ( i<args.length-1 )
            clauses.append(" AND ");
        }
        // Exécution requête etc..
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //...
    MyBeanDAO dao = ...
    dao.findMyBean("nom=Toto", "age<20", "sexe=M");
    J'utilise un amélioration de Java(mais je ne le souviens plus du nom*) qui permet d'écrire String... au lieu d'obliger l'utilisation d'un tableau de String et donc de rendre le code (un peu) plus propre sur l'appel de la méthode.

    Et pour le sinjections, je ne vois pas trop le risque, l'utilisateur n'a quand même pas un accès direct à ces méthodes, c'est le développeur. Si ça lui chante de vider les tables.. c'est son problème.

    * Edit : J'ai retrouvé le nom : l'ellipse

  10. #10
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Là, l'autre problème que tu auras c'est un argument contenant une apostrophe... qu'il faudra doubler...
    Il serait quand même mieux d'utiliser les fonctionnalités de positionnement des paramètres en fonction de leur type (comme avec les PreparedStatement JDBC), ça éviterait ce genre d'erreur...
    La méthode avec une Map fonctionnerait et ce n'est pas loin de ce que tu fais là
    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Invité
    Invité(e)
    Par défaut
    Ok, merci pour vos conseils. Je vais encore réfléchir un peu.
    Mais je suis tout triste car j'avais trouvé une utilisation de l'ellipse qui me semblait bonne...

    Grande chances que je me tourne vers l'utilisation de HashMap. N'empêche que dans mes littératures j'ai encore vu du SQL like avec les EJB3.0 docn je reste un peu vers cette seconde idée..

    Je clos le sujet mais vos réactions sont toujours les bienvenues

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    c'est un peu toujours le même combat... tu as les anti sql et les pro... philosophique...

    Personnellement, je n'ai aucun problème avec JDBC ou EJB3 ou Hibernate.
    Mettre une portion de requête "sql like" dans un ejb3 est, à mon sens, très adaptée, dans tous les cas, c'est l'ejb qui représente l'abstraction de la base, pas la façon interne d'extraire... Idem avec les pojos d'hibernate...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Implémenter le patron de conception DAO par les tests
    Par thierryler dans le forum Général Java
    Réponses: 7
    Dernier message: 02/01/2013, 14h37
  2. [Struts1 - Hibernate3] Conception DAO pour requête "filtre"
    Par LordBob dans le forum Frameworks Web
    Réponses: 4
    Dernier message: 12/02/2011, 01h00
  3. [EJB] Conception DAO et EJB
    Par hocdz dans le forum Java EE
    Réponses: 3
    Dernier message: 14/10/2009, 14h24
  4. Réponses: 24
    Dernier message: 29/08/2005, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo