简体   繁体   English

与Doctrine2(Symfony2)的内部联接

[英]InnerJoin with Doctrine2 (Symfony2)

I am new to Symfony2 (~ 1 week). 我是Symfony2的新手(〜1周)。 I have a manyToOne on the BudgetData Entity that joins the id of the Entity BudgetDescription. 我在BudgetData实体上有一个manyToOne,它加入了实体BudgetDescription的ID。 I created a SQL query that I want to replicate for Doctrine : 我创建了一个要为Doctrine复制的SQL查询:

SELECT d, e
FROM BudgetData d
INNER JOIN BudgetDescription e 
ON d.budgetDescription_id = e.id

BudgetData table : id, year, value, budgetDescription_id (FK) BudgetData表:id,年,值,budgetDescription_id(FK)

BudgetDescription table : id, descriptionName 预算描述表:ID,descriptionName

What I tried so far : 到目前为止我尝试过的是:

    $em = $this->getDoctrine()->getManager();
    $qb = $em->getRepository('MainBundle:BudgetData');
    $qb = $em->createQueryBuilder('d');

    $dataQuery = $qb->select('d, c')
                    ->innerJoin('c.id', 'c', Join::ON, 'd.budgetDescription_id = c.id')
                    ->getQuery();

    $dataQuery = $dataQuery->getArrayResult();

Any idea how I can do the SQL query but in DQL ? 知道如何在DQL中执行SQL查询吗?

Thank you ! 谢谢 !

if you have a relation in your BudgetDataEntity called budgetDescription with an attribute $budgetDescription, in the BudgetDataRepository you could do : 如果您在BudgetDataEntity中有一个名为budgetDescription且具有属性$ budgetDescription的关系,则可以在BudgetDataRepository中执行以下操作:

    public function myInnerJoin()
    {

           $qb = $this->createQueryBuilder('f') 
                ->select('f','g')
                ->innerJoin('f.budgetDescription', 'g'); 

           return $qb->getQuery()->getArrayResult();
    }

and in controller 并在控制器中

$repository = $this->getDoctrine()->getManager()->getRepository('AcmeBundle:BudgetData');
$result = $repository->myInnerJoin(); 

That is my guess 那是我的猜测

The better solution is to leverage the benefits of the Doctrine ORM. 更好的解决方案是利用准则ORM的优势。 In a nutshell, create entity classes with the proper associations defined and then, as necessary, create custom query methods in the entity's repository class to do your lookups. 简而言之,创建具有正确定义的关联的实体类,然后根据需要在实体的存储库类中创建自定义查询方法以进行查找。 Example: 例:

The BudgetData entity: BudgetData实体:

use Doctrine\ORM\Mapping as ORM;
use MainBundle\Entity\BudgetDescription;

...

/**
 * @ORM\Table(name="budget_data")
 * @ORM\Entity(repositoryClass="MainBundle\Repository\BudgetDataRepository")
 */
class BudgetData
{
    // properties here

    /**
     * @ORM\ManyToOne(targetEntity="BudgetDescription")
     * @ORM\JoinColumn(name="category", referencedColumnName="id", nullable=false)
     */
    private $budgetDescription;

    ...

    /**
     * Set budgetDescription
     *
     * @param BudgetDescription $budgetDescription
     * @return BudgetData
     */
    public function setBudgetDescription(BudgetDescription $budgetDescription)
    {
        $this->budgetDescription = $budgetDescription;

        return $this;
    }

    /**
     * Get budgetDescription
     *
     * @return BudgetDescription
     */
    public function getBudgetDescription()
    {
        return $this->budgetDescription;
    }
}

The BudgetDescription entity: BudgetDescription实体:

use Doctrine\ORM\Mapping as ORM;

...

/**
 * @ORM\Table(name="budget_description")
 * @ORM\Entity
 */
class BudgetDescription
{
    // properties here
    ...

    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="IDENTITY")

     */
    private $id;

    ...
}

Now Doctrine will manage this association for you so that all you need to do to get the BudgetDescription entity from BudgetData is to call the getBudgetDescription() method of a BudgetData instance, like this: 现在,Doctrine将为您管理此关联,以便从BudgetData获取BudgetDescription实体BudgetData就是调用BudgetData实例的getBudgetDescription()方法,如下所示:

$budgetData = $em->getRepository('MainBundle:BudgetData')->findOneById(3);
$budgetDescription = $budgetData->getBudgetDescription();

And voila. 和瞧。 In the above example, Doctrine retrieves a budget_data row with ID=3 in your database and hydrates a BudgetData entity with that data. 在上面的示例中,Doctrine在数据库中检索ID = 3的budget_data行,并使用该数据BudgetData实体。 And then when you call the getBudgetDescription() method, it fetches the associated row in the budget_description table and hydrates a BudgetDescription entity. 然后,当您调用getBudgetDescription()方法时,它将获取budget_description表中的关联行,并budget_description BudgetDescription实体。 You can eliminate that second look up by using fetch="EAGER" in your association annotation. 您可以通过在关联注释中使用fetch="EAGER"消除第二次查找。 By default though, Doctrine lazy loads data so it only loads what you need. 但是,默认情况下,Doctrine惰性加载数据,因此它仅加载您需要的内容。

I hope this helps. 我希望这有帮助。

ps I would recommend prefixing your primary and foreign key's with the names of the tables. ps我建议您在主键和外键之前加上表名。 So in the example above, your budget_data table would have a foreign key budget_description_id and your budget_description table would have a primary key budget_description_id . 因此,在上面的示例中,您的budget_data表将具有外键budget_description_id而您的budget_description表将具有主键budget_description_id There are many good reasons for doing this not the least of which is clarity of associations between tables. 这样做有很多充分的理由,其中最重要的是表之间关联的清晰性。

I used a simple query. 我使用了一个简单的查询。 The following code works, but if you have any other (better) solution, I would love to have it. 以下代码可以工作,但是如果您有其他(更好)的解决方案,我很乐意拥有。

$em = $this->getDoctrine()->getManager();

$qb = $em->createQuery("SELECT d.year, d.value, e.descriptionName FROM MainBundle:BudgetData d INNER JOIN MainBundle:BudgetDescription e WITH d.category = e.id");

$newQuery = $qb->getArrayResult();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM