[英]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:
例:
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;
}
}
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.