You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony新手求助:SQL转QueryBuilder及仓库选择问题

How to Convert Your SQL Query to Symfony QueryBuilder & Choose the Right Repository

Hey there! Let's break this down for you step by step since you're new to Symfony—no worries, we've all stumbled through QueryBuilder at first.

First: Which Repository Should You Use?

This boils down to your business intent:

  • If you're trying to get a list of users (who have orders), putting this in UserRepository makes the most semantic sense. The end result is a collection of User entities, so keeping the query where you fetch users feels intuitive and aligns with how you'll likely use the data.
  • You could write it in CommandeRepository too, but that's more focused on orders than the users themselves. Stick with UserRepository for clarity.

Converting Your SQL to QueryBuilder

First, make sure your entities have the proper associations set up (this will make QueryBuilder way simpler than writing raw JOIN conditions):

  • In your User entity, add a OneToMany relationship to Commande:
    /**
     * @ORM\OneToMany(targetEntity=Commande::class, mappedBy="user")
     */
    private $commandes;
    
  • In your Commande entity, add a ManyToOne relationship back to User:
    /**
     * @ORM\ManyToOne(targetEntity=User::class, inversedBy="commandes")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;
    

With those associations in place, here's how to build the query in UserRepository:

// src/Repository/UserRepository.php
use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    public function findUsersWithOrders()
    {
        return $this->createQueryBuilder('u')
            // Select the user ID from commande and all user fields
            ->select('c.user_id', 'u')
            // Join users to their orders (uses the association we set up)
            ->innerJoin('u.commandes', 'c')
            // Add distinct to avoid duplicate user entries (since one user can have multiple orders)
            ->distinct()
            ->getQuery()
            ->getResult();
    }
}

A Quick Note on Your Original SQL

Your original query uses a LEFT JOIN, but since you want users who have orders, an INNER JOIN is more appropriate—it automatically filters out users with no orders. If you really need the LEFT JOIN (e.g., to include orders that might not have a user attached), you can swap innerJoin for leftJoin and add a ->where('u.id IS NOT NULL') clause to filter out null user entries.

If You Did Want to Use CommandeRepository (Just for Reference)

If for some reason you prefer to start from the Commande side, here's that version:

// src/Repository/CommandeRepository.php
use Doctrine\ORM\EntityRepository;

class CommandeRepository extends EntityRepository
{
    public function findUsersWithOrders()
    {
        return $this->createQueryBuilder('c')
            ->select('c.user_id', 'u')
            ->leftJoin('c.user', 'u')
            ->where('u.id IS NOT NULL')
            ->distinct()
            ->getQuery()
            ->getResult();
    }
}

Just remember: the UserRepository approach is cleaner for your specific use case of fetching users.

内容的提问来源于stack exchange,提问作者Rudy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:13:02