Symfony / Twig - 递归减少数据库查询

时间:2017-12-03 04:17:09

标签: symfony doctrine-orm twig

我在树枝模板中有我的类别树:

...
    /**
     * One Category has Many Subcategories.
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent", cascade={"persist"}))
     */
    private $children;
    /**
     * Many Subcategories have One Category.
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children", cascade={"persist"})
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    private $parent;
...
    /**
     * Add child
     *
     * @param \App\Entity\Product\Category $child
     *
     * @return Category
     */
    public function addChild(\App\Entity\Product\Category $child): Category
    {
        $this->children[] = $child;
        return $this;
    }

    /**
     * Remove child
     *
     * @param \App\Entity\Product\Category $child
     */
    public function removeChild(\App\Entity\Product\Category $child)
    {
        $this->children->removeElement($child);
    }

    /**
     * Get children
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getChildren(): Collection
    {
        return $this->children;
    }

    /**
     * Set parent
     *
     * @param \App\Entity\Product\Category $parent
     *
     * @return Category
     */
    public function setParent(\App\Entity\Product\Category $parent = null): Category
    {
        $this->parent = $parent;
        return $this;
    }

    /**
     * Get parent
     *
     * @return \App\Entity\Product\Category
     */
    public function getParent()
    {
        return $this->parent;
    }
...

如果我在每个类别中有6个类别和7个子类别,则会创建+ - 53个数据库查询。

有没有办法减少这个数字? 我在doctrine中使用useResultCache(true),但看起来它没有从缓存中加载(至少不是在开发模式下)。

你是如何处理类别树的?

更新: 实体:

colorStops[i] = color[i].pos : color[i].color;

1 个答案:

答案 0 :(得分:0)

根据我的评论:你必须JOIN你的子类别。我假设你现在正在做这样的事情来检索你的categories

   public function getCategories()
    {
        return $this->getEntityManager()->createQueryBuilder()
            ->select("category")
            ->from("App:Category", "category")
            ->where("category.parent IS NULL")
            ->getQuery()->getResult();
     }

因此,如果您现在正在迭代此类别数组并尝试访问children属性,则将为每个导致此类大量数据库查询的子项触发子查询。

相反,你应该JOIN他们这样:

 public function getCategories()
    {
        return $this->getEntityManager()->createQueryBuilder()
            ->select("category", "subcat")
            ->from("App:Category", "category")
            ->leftJoin("category.children", "subcat")
            ->where("category.parent IS NULL")
            ->getQuery()->getResult();
    }

如果您现在迭代categories并访问children属性,则不会触发额外的查询!

使用上面的查询和twig中的这个片段只会产生一个数据库查询:

   {% for category in categories %}
        <p>cat={{ category.id }}</p>

        {% for subcat in category.children %}
            <p>subcat={{ subcat.id }}</p>
        {% endfor %}
        <hr>
    {% endfor %}