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

Hibernate Java Discussion :

Optimisation d'une requête Criteria


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut Optimisation d'une requête Criteria
    Bonjour,

    je vous présente une petit problème d'optimisation :

    J'ai une table User et une table Game. Entre les deux, une many-to-many, appellée Player, définie comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <class name="Player" table="Player">
            <id name="id" column="id">
                <generator class="native"/>
            </id>
            <property name="status"/>    
            <many-to-one name="user" column="login" class="User"/>
            <many-to-one name="game" column="gameId" class="Game"/>
            (...)
        </class>
    Donc, l'objectif est maintenant d'aller chercher dans la base toutes les parties auxquelles un User est associé via cette table Player. Voici mon code DAO non optimisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public List<Game> getUserGames(String login) {
            /* SELECT * FROM GAME g, PLAYER p WHERE p.gameId = g.gameId and p.login = login */
            Criteria c1 = getSession().createCriteria(Game.class);
            Criteria c2 = c1.createCriteria("players");
            Criteria c3 = c2.createCriteria("user");
            c3.add(Restrictions.eq("login", login));
            return c1.list();
        }
    Ce code fonctionne, mais me crée deux jointures : une Game-Player, et une seconde Player-User. C'est une de trop puisqu'on connait l'identifiant de User (=login) qui est la clé étrangère de la table Player. Il suffirait alors de pouvoir mettre la restriction sur c2 plutôt que sur c3. Mais c'est là qu'est le soucis : le mapping de Player ne définit pas de "propriété" login...

    Une idée?

  2. #2
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    alors si j'ai bien suivi ce que tu as expliqué, la clé primaire de user c'est le varchar login, que tu réutilises dans player en tant que clé étrangère ?

    dans ce cas as-tu essayé quelque chose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            Criteria c1 = getSession().createCriteria(Game.class);
            Criteria c2 = c1.createCriteria("players");
            c2.add(Restrictions.eq("user.login", login));
    voire même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
            Criteria c1 = getSession().createCriteria(Game.class).createCriteria("players").add(Restrictions.eq("user.login", login));
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    C'est tout à fait ça!
    Merci pour ton aide!

    Peux-tu m'expliquer exactement ce que ça fait?
    Quelle est donc la sémantique de ce "user.login"?
    Car si je fais "user.email" par exemple, ça me lance une exception.
    Que veut dire le point dans cette expression?

  4. #4
    Membre éprouvé Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Points : 1 050
    Points
    1 050
    Par défaut
    le point sert à accéder à une propriété: dans mon expression "user.login" j'accède par exemple à la propriété login de l'objet user existant dans players.
    tu t'en sers par exemple avec les alias:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Criteria c1 = getSession().createCriteria(Game.class)
            .createCriteria("players", "pl") // je crée un alias
            .add(Restrictions.eq("user.login", login));
    // Supposons que tu aies une propriété Name dans player
    c1.add(Restrictions.eq("pl.Name", login));
    mais dans ce cas précis, tu ne peux accéder qu'aux clés primaires/étrangères puisque la clé est le seul élément de user contenu dans player.
    Du coup, Hibernate cherche la valeur donnée (ton String login ici) dans la colonne login de player, sans joindre la table user, ce que tu voulais.

    Donc forcément user.email lance une erreur puisque qu'il n'y a pas de colonne email dans player, tu as besoin de user pour ça

    j'espère avoir été clair
    Nous les geeks, c'est pas qu'on a une case en moins, c'est juste qu'on compte à partir de zéro.
    Plus les choses changent, plus elles restent les mêmes

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    Oui nickel, j'ai tout compris

    Merci beaucoup!

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

Discussions similaires

  1. Optimisation d'une requête
    Par Louis-Guillaume Morand dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 20/12/2005, 18h21
  2. Optimisation d'une requête d'insertion
    Par fdraven dans le forum Oracle
    Réponses: 15
    Dernier message: 01/12/2005, 14h00
  3. Optimisation d'une requête patchwork
    Par ARRG dans le forum Langage SQL
    Réponses: 1
    Dernier message: 11/09/2005, 15h23
  4. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  5. [DB2] Optimisation d'une requête
    Par ahoyeau dans le forum DB2
    Réponses: 7
    Dernier message: 11/03/2005, 17h54

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