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

JDBC Java Discussion :

Problème de compréhension du modèle DAO


Sujet :

JDBC Java

  1. #1
    Membre du Club

    Homme Profil pro
    Lycéen
    Inscrit en
    Mai 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2011
    Messages : 22
    Points : 49
    Points
    49
    Par défaut Problème de compréhension du modèle DAO
    Bonjour. Je viens tout juste découvrir le pattern DAO que je me pose quelque question. Par exemple sur OCR Herby propose
    Nom : 041029D1jJZn14.png
Affichages : 689
Taille : 3,4 Ko

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Citation Envoyé par cultureman Voir le message
    je me pose quelque question
    Laquelle ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre du Club

    Homme Profil pro
    Lycéen
    Inscrit en
    Mai 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2011
    Messages : 22
    Points : 49
    Points
    49
    Par défaut
    Oui , un oubli.
    Pour la méthode find , il se peut qu'on veuille faire la recherche en fonction d'un autre critère que l'id. Dans ce cas faudrait-il utiliser 4 interfaces(pour chaque xxxDAO)?

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Le pattern DAO définit juste un moyen d'accèder à une source de données, de manière indépendant de cette source (que ça soit une base de données JDBC, un serveur de fichiers, un système de persistence d'objet, etc).

    Il n'y a qu'une seule interface ici, qui définit le CRUD (Create/Read/Update/Delete) : les 4 actions qu'on peut avoir à faire. On pourrait découper en plusieurs interfaces, si on voulait séparer les notions "Lecture Seule" et "Lecture/Ecriture". La méthode find(id) donnée dans l'exemple, n'est qu'une version simplifiée de l'action Read. En plus rien n'empêche d'avoir plusieurs méthodes pour chaque action. Par exemple, on peut avoir une méthode find(id) pour trouver l'objet suivant son id, et une méthode find(IFilter) avec IFlter une interface fonctionnelle, pour trouver des enregistrements selon une combinaison de critères quelconques. tu peux même avoir une méthode getAll() (qui retourne un itérateur paginé, pas la liste de tous les enregistrement...).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre du Club

    Homme Profil pro
    Lycéen
    Inscrit en
    Mai 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2011
    Messages : 22
    Points : 49
    Points
    49
    Par défaut
    Merci beaucoup pour votre réponse. J'ai donc essayé de faire une méthode trouver un peu générique

    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
    20
     
     
    public OperateurPhysique[] trouver(String filtre, Object... objs) 
    {
            ResultSet res;
            OperateurPhysique[] ops = null;
            String sql = "SELECT * FROM matable WHERE ";
            StringTokenizer tokens = new StringTokenizer(filtre, ";");
            int t = objs.length;
            for(int i = 0 ; i < t ; i++)
            {
                if(i == 0)
                    sql += tokens.nextToken() + " =  " + objs[i];
                else
                    sql += "AND " + tokens.nextToken() + " =  " + objs[i];
     
            }
     
           //reste du code
        }

    Ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    trouver("nom;prenom" , "Lupin" , "Arsene")
    exécutera la requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM matable WHERE nom = 'Lupin' AND prenom = 'Arsène'
    Bien sur je compte utiliser des requêtes préparées plus tard.
    Qu'en pensez vous?

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par cultureman Voir le message
    Bien sur je compte utiliser des requêtes préparées plus tard.
    Qu'en pensez vous?
    Je pense qu'il vaudrait mieux utiliser les PreparedStatement au plus tôt. Par contre, attention à la problématique d'être très lié à une base de données relationnelle SQL, dans le cadre général d'un DAO.
    Dans la pratique, comme il est plus complexe de faire un DAO complètement générique du point de vue du système de persistance, on peut faire, comme tu as fait, un filtre SQL si on a un SGBD SQL, surtout qu'il y a peu de risque que cela change un jour dans l'application.

    Mais, ça ne coûte pas grand chose et ce n'est pas spécialement très complexe de faire un filtre un peu plus abstrait, donc au lieu d'une chaîne de faire des interfaces pour manipuler un arbre de conditions, et faire une unique implémentation concrète qui transforme cet arbre en SQL. Ça prend beaucoup plus de temps quand même que pour une simple String, mais par rapport à un filtre pour PreparedStatement, on a des éléments similaires.
    Ainsi, migrer d'une base vers autre chose, n'impliquera que l'implémentation du DAO concrète, pas les classes qui l'invoquent. De même pour le parcourt du résultat, qui devrait se faire en externe (pour rendre totalement transparent le parcourt de résultat réduit, complet, partiel, paginé, etc..., une sorte ResultSet DAO). C'est en tout cas un exercice intéressant à faire dans le cadre du travail sur les DAO.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Membre du Club

    Homme Profil pro
    Lycéen
    Inscrit en
    Mai 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Burkina Faso

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2011
    Messages : 22
    Points : 49
    Points
    49
    Par défaut
    Merci. Mais disons que je ne suis pas vraiment un expert en ce qui concerne les interfaces. Pour la deuxième suggestion, ma méthode devrait prendre en paramètre un objet implémentant l'interface (disons ResultSetDAO) , c'est ça? Je ne sais pas trop comment faire pour rendre le filtre plus abstrait.

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par cultureman Voir le message
    Merci. Mais disons que je ne suis pas vraiment un expert en ce qui concerne les interfaces. Pour la deuxième suggestion, ma méthode devrait prendre en paramètre un objet implémentant l'interface (disons ResultSetDAO) , c'est ça? Je ne sais pas trop comment faire pour rendre le filtre plus abstrait.
    Pour faire une Interface, il suffit de lister ce dont on va avoir besoin. Si je dois faire une interface qui doit récupérer une propriété, je vais y mettre une méthode String getString(String name) par exemple, plus une méthode qui permet de récupérer une propriété int, une pour une propriété boolean, etc. Dans le DAO de l'application sur laquelle je bossais il n'y a pas longtemps, on avait une méthode getProperty(String name) qui retournait un IPropertyValue<T>, avec en implémentation concrète un StringValue, un IDValue, un CollectionValue, pour les éléments liés (lien 1-n), etc.

    ResultSetDAO, ce serait plutôt le type de retour. Une interface avec une méthode qui permet d'avancer dans le résultat (une méthode hasNext() et une méthode next() par exemple), et qui permet de récupérer toutes les propriétés (donc la liste de noms de propriétés, et pour chaque propriété, son type (java) et sa value), ou alors c'est next qui retourne un enregistrement (une instance d'une classe qui a ces méthodes). Ensuite, on peut toujours l'enrichir, pour avoir une méthode qui donne le nombre d'enregistrements par exemple.

    Le filtre, c'est juste un arbre de noeud. Dans l'optique, encore une fois, d'être très générique et, donc, indépendant de la façon de stocker le données. On pourrait également décider de mettre au point un petit langage d'expressions, dont l'arbre serait l'AST (Abstract Syntax Tree). Mais si tu ne te sens pas capable de le faire, tu peux te contenter pour commencer de faire un DAO qui ne traite que du SQL/Statement ou SQL/PreparedStatement.

    Sinon dans l'optique de modéliser l'arbre par les classes (sans définir un langage et donc faire un parser) Chaque noeud correspond à un critère "unitaire". L'arbre/Expression est la combinaison des critères. Il y a des critères sans niveau (un arbre à un seul noeud, comme une égalité par exemple), et des critères multiples, à plusieurs niveaux (par exemple, pour faire un AND ou un OR).
    Par exemple, voici un arbre (chaque ligne est un nœud) :
    ET 
         a = 42
         b = "abcd"
         c commence par "a"
         OU 
              x <= 10
              x > 100
    
    Qui sera traduit au final en SQL de prepared statement : par "a=? AND b = ? AND c like ? AND ( x<=? OR X>? )"

    Le critère le plus simple, c'est :
    • un nom d'objet (de table en SQL)
    • un nom de propriété (colonne de table en SQL)
    • un opérateur de comparaison (=, >, commence par, etc.)
    • une valeur à comparer

    Ensuite, tu pourras avoir des critères à 2 valeurs (avec un opérateur entre ... et ...), à plusieurs valeurs (avec un opérateur "parmi"...),

    Ce qu'il faut c'est être capable de produire du SQL, ou n'importe quelle autre syntaxe pour exprimer un filtre, en théorie. C'est là l'une des complexité, c'est-à-dire que tu peux tomber dans un travers qui fera que tu ne peux générer que du SQL au final. Cependant, c'est une approche qui simplifie le travail intellectuel, et tu pourras toujours sortir cette partie ensuite, pour traiter une autre façon de faire le filtre si besoin. L'avantage c'est que ça n'aura aucun impact sur la manière de construire l'arbre, donc sur le code métier. Par exemple si tu commences par faire une interface pour représenter un nœud qui a une méthode toSQL() qui génère un PreparedStatementBuilder (une classe qui permet de créer un preparedStatement prêt à être exécuté, avec ses paramètres injectés), ce n'est pas très compliqué à faire (c'est juste une classe, qui a un attribut StringBuilder, et une liste de valeurs (avec un moyen de sélectionner le bon injecteur, donc soit un type de données, soit directement l'invocation de l'injection, en utilisant un lambda)).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Comme le disais joel.drigo, l'exemple que tu montres est un cas particulier (CRUD).
    La méthode find est lié à la clé primaire de l'enregistrement dans la table et ne renvoit qu'une seule instance.

    Il ne faut pas la confondre avec une méthode de recherche qui pourrait renvoyer une liste d'objet. Là, effectivement, tu auras à composer avec des arguments de filtre variable.
    Généralement, on utilise une couche générique pour la partie CRUD et une couche spécialisée qui l'étend ou qui la contient pour la partie implémentation dans le cadre d'une application donnée. On est en plein dans le cadre du pattern facade, très utile surtout avec les EJB (vu qu'on peut être ammené à changer de conteneur entre l'application demandeuse et la couche EJB)

    Pour la méthode de recherche, il y a plusieurs façon de procéder, ceci-dit, ton exemple avec un paramètre "quels champs" et un autre paramètre "valeur de comparaison" me paraît tout de suite limité, dans l'idée, j'aurais préféré un nombre dynamique de paramètres contenant le couple "champ=valeur" parce ça rendrait plus lisible, par exemple :
    - "champ1=valeur"
    - "champ1=valeur1|valeur2|valeur3"
    Dans les 2 cas, il sera difficile de traiter des relations entre les conditions (and/or)...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. [Débutant] problème de compréhension
    Par Sylvester dans le forum Général Java
    Réponses: 18
    Dernier message: 21/07/2005, 09h16
  2. Réponses: 5
    Dernier message: 11/04/2005, 10h21
  3. [C#] Problème de compréhension de System.Convert ET Provider
    Par papouAlain dans le forum Windows Forms
    Réponses: 5
    Dernier message: 18/11/2004, 21h52
  4. onclipevent (problème de compréhension)
    Par stephane eyskens dans le forum Flash
    Réponses: 8
    Dernier message: 24/09/2003, 15h09
  5. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07

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