内部加入主义2(Symfony2)

时间:2014-10-31 14:45:20

标签: php symfony doctrine-orm

我是Symfony2的新手(约1周)。我在BudgetData实体上有一个manyToOne,它加入了Entity BudgetDescription的id。 我创建了一个我想要为Doctrine复制的SQL查询:

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

BudgetData表: id,year,value,budgetDescription_id(FK)

BudgetDescription表: id,descriptionName

到目前为止我尝试了什么:

    $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();

知道如何在DQL中执行SQL查询吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

如果您的BudgetDataEntity中有一个名为budgetDescription的关系,其属性为$ budgetDescription,您可以在BudgetDataRepository中执行以下操作:

    public function myInnerJoin()
    {

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

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

并在控制器中

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

这是我的猜测

答案 1 :(得分:1)

更好的解决方案是利用Doctrine ORM的优势。简而言之,创建具有定义的正确关联的实体类,然后根据需要在实体的存储库类中创建自定义查询方法以进行查找。例如:

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;
    }
}

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;

    ...
}

现在,Doctrine将为您管理此关联,以便您从BudgetDescription获取BudgetData实体所需要做的就是调用getBudgetDescription()的{​​{1}}方法例如,像这样:

BudgetData

瞧。在上面的示例中,Doctrine在数据库中检索ID为3的$budgetData = $em->getRepository('MainBundle:BudgetData')->findOneById(3); $budgetDescription = $budgetData->getBudgetDescription(); 行,并使用该数据保存budget_data实体。然后当您调用BudgetData方法时,它会获取getBudgetDescription()表中的关联行并保留budget_description实体。您可以在关联注释中使用BudgetDescription来消除第二次查找。但默认情况下,Doctrine延迟加载数据,因此它只加载您需要的内容。

我希望这会有所帮助。

P.S。我建议在主键和外键前加上表的名称。因此,在上面的示例中,您的fetch="EAGER"表将具有外键budget_data,而您的budget_description_id表将具有主键budget_description。这样做有很多很好的理由,其中最重要的是表格之间关联的清晰度。

答案 2 :(得分:0)

我使用了一个简单的查询。以下代码有效,但如果您有任何其他(更好)解决方案,我很乐意拥有它。

$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();