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

Doctrine2 PHP Discussion :

query vs querybuilder


Sujet :

Doctrine2 PHP

  1. #1
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut query vs querybuilder
    Bonsoir,

    En dehors de l'aspect "esthétique" dans l'écriture des requêtes, quels sont les arguments pour utiliser query plutôt que querybuilder ? rapidité, plus ou moins de possibilités , ....
    D'autre part, j'ai vu qu'on pouvait mettre les requêtes DQL directement dans le controller sans passer par le repository. Quelle est la meilleure méthode et pourquoi ? Je suppose que c'est le repository ?

    Merci pour vos conseils.

  2. #2
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Query avec DQL ou Querybuilder c'est sensiblement la même chose.

    Il n'est pas conseillé de mettre tes requêtes dans la partie controller, car le framework est justement fait pour ne pas faire cela. Idem pour la partie twig. Le but de symfony 2 est de structurer le code et de séparer la couche métier (model) de la vue (twig) et du controller(action) . Le controler ne doit comprendre que la partie "aiguillage" de ton code. Les bonnes pratiques veulent qu'une action d'un controller contienne au max 20 lignes.

    Si tu veux l'intégralité des best practices : http://symfony.com/doc/current/best_...ces/index.html

    Après il y a certains points qui sont discutables, mais pour un débutant je pense que c'est une bonne chose d'y coller au maximum

  3. #3
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut
    Bonjour,

    Merci pour ta réponse. Je m'y attendais un peu ....
    Par contre, il me semble que le résultat renvoyé par la requête DQL n'est pas le même si l'on est dans le repository ou dans le controller.
    Dans le repository il renvoie un objet dans le controller. Voir pièces jointes.

    Si on ne veut pas tout ramener comme dans le repository, on peut par exemple créer une fonction privée dans le contrôleur ?

    Merci pour les conseils. Je vais aussi aller lier les bonnes pratiques
    Images attachées Images attachées   

  4. #4
    Membre averti

    Inscrit en
    Juin 2008
    Messages
    307
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 307
    Points : 364
    Points
    364
    Par défaut
    Non normalement tu as la même chose. La j'ai l'impression que tu hydrate pas tes résultats de la même manière. Peux tu poster les 2 portions de code que tu exécute .

  5. #5
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut
    Bonsoir et merci pour ta réponse.
    Effectivement, je commence à percevoir l'hydratation.
    Je viens de tester l'appel suivant au repository :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	public function getLesEmployesSalaireAction() {
    		$employes = $this->getDoctrine()->getRepository('BdlsDoctrineBundle:Employe')->getLesEmployesSalaire();
    Je n'obtiens pas la même chose si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public function getLesEmployesSalaire() {
    		$dql = $this->createQueryBuilder('e');
    		$dql
    				->addSelect('e.id, e.nomemp')
    				->where('e.salaire > 15000')
    		;
    J'obtiens un tableau d'objets

    alors que si je fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $dql = $this->_em->createQueryBuilder();
    		$dql
    				->addSelect('e.id, e.nomemp')
    				->from($this->_entityName, 'e')
    				->where('e.salaire > 15000')
    		;
    J'obtiens un tableau de valeurs.

    Je n'ai pas encore saisi le pourquoi du comment, ni ce qui est bon de ce qui est moins bon comme pratique. Dans ce cas là, la deuxième solution me semble meilleure car je ramène moins de choses de la BD.
    Dans la première solution, je ramène toutes les infos des employés alors que je n'en ai pas besoin. Pour less agrégats (group by), la deuxième solution me parait la plus adaptée.
    J'ai du mal à trouver une doc qui explique cela très bien. Si vous an avez ...
    En tous cas, merci pour vos conseils éclairés.
    Cordialement

  6. #6
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Dans le premier cas, $this->createQueryBuilder('e'); te retourne un queryBuilder qui possède déjà un select et un from car il s'agit d'une méthode de ton repository et non directement de l'entityManager.
    Le FROM correspond à l'entité liée à ton repository et le SELECT à tous les champs de cette entité.

    Dans le deuxième cas, tu passes par l'entityManager pour créer un QueryBuilder, il ne correspond donc à aucune entité. Tu as besoin de définir un SELECT et un FROM pour savoir quoi retourner.

    ---

    Dans le premier cas, le fait d'ajouter ->addSelect('e.id, e.nomemp') va faire que tu auras ces 2 champs en double dans le résultat de la requête (puisque tous les champs de l'entité sont déjà dans le select implicite). Du coup ces deux valeurs sont ajoutées en plus de l'objet qu'il a pu mapper.

    Dans le deuxième cas, tu ne retournes que les valeurs définies dans le addSelect, puisqu'il n'y a pas de select prédéfini.

    ---

    Pour illustrer voici le code que tu utilises dans le premier cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    /**
     * Creates a new QueryBuilder instance that is prepopulated for this entity name.
     *
     * @param string $alias
     *
     * @return QueryBuilder
     */
    public function createQueryBuilder($alias)
    {
        return $this->_em->createQueryBuilder()
            ->select($alias)
            ->from($this->_entityName, $alias);
    }

    Dans tous les cas les requêtes n'ont pas leur place dans le contrôleur. Quel que soit le prétexte : c'est mal !
    Leur place ce sont les repository : point.

    Si tu ne souhaites pas récupérer toutes les valeurs mais utiliser les repository, tu dois créer ton QueryBuilder depuis l'entity manager (disponible de puis la classe repository par défaut si je ne dis pas de bêtise) et non directement depuis la méthode du Repository. De cette manière, tu seras libre de mettre ce que tu veux dans ton select et ton from.

    Du coup au lieu de faire : $this->createQueryBuilder('e') tu vas plutôt faire $this->_em->createQueryBuilder().

    Une autre méthode est de créer des objets partiels => http://doctrine-orm.readthedocs.org/...l-objects.html

    Attention cependant, l'utilisation de cette technique nécessite de bien maitriser ce qu'on fait, car cela peut provoquer des effets de bord.

    ++

  7. #7
    Membre régulier
    Profil pro
    Développeur
    Inscrit en
    Janvier 2010
    Messages
    232
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Janvier 2010
    Messages : 232
    Points : 112
    Points
    112
    Par défaut
    Merci pour cette réponse argumentée.
    Je commence à y voir plus clair avec l'hydratation. Effectivement, j'ai tendance à trop penser BD alors qu'il faut penser objet.
    Tout le code que je t'ai montré était dans le repository, là il n'y a plus de problème.
    Bonne soirée et encore merci pour le temps que tu as mis à me répondre

Discussions similaires

  1. Connection avec MS Query (Excel) via ODBC MySQL
    Par javigle dans le forum Installation
    Réponses: 7
    Dernier message: 23/11/2003, 22h03
  2. Query Begin et Commit son sur un bateau....
    Par faoz75 dans le forum Requêtes
    Réponses: 5
    Dernier message: 15/08/2003, 12h48
  3. Je ne retrouve pas ma SP dans Query analyser
    Par WOLO Laurent dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 14/07/2003, 13h43
  4. Query data set
    Par Sandra dans le forum JBuilder
    Réponses: 3
    Dernier message: 20/01/2003, 11h08
  5. [XMLRAD] Décoder Request.Query
    Par Sylvain Leray dans le forum XMLRAD
    Réponses: 8
    Dernier message: 10/01/2003, 17h40

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