2017-12-03 200 views
0

我在樹枝模板我的類別樹:的Symfony /嫩枝 - 遞歸下降的數據庫查詢

{% for category in categories %} 
    <li> 
     <div class="li"><a href="{{ path('accessories_list', { 'category' : category.url }) }}">{{ category.name|trans({}, 'categories')|raw }}</a></div> 
     {% if category.children is not empty %} 
      <ul> 
       {% include "default/_menu_links.html.twig" with {'categories':category.children} only %} 
      </ul> 
     {% endif %} 
    </li> 
{% endfor %} 

它創建+ - 53個數據庫查詢,如果我有6類,並在每個單一類別7小類。

有沒有辦法減少這個數字? 我在doctrine中使用useResultCache(true),但看起來它不是從緩存中加載(至少不是在開發模式下)。

你如何處理類別樹?

UPDATE: 實體:

... 
    /** 
    * 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; 
    } 
... 
+0

通常,如果你的數據庫查詢的量取決於所獲取的數據(更多數據=更多的查詢),你應該考慮使用JOIN語句來減少數據庫查詢。如果您可以提供您的學說實體的一些代碼將會很有幫助。 – baris1892

+0

@ radon66嗨,感謝您的回覆。更新我的問題。所以你認爲每天一次在json中生成類別會更好,緩存並在網站上使用? – user8810516

回答

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財產,沒有多餘的查詢將被解僱了!

使用上面的查詢,這個片段在樹枝將導致只在一個數據庫查詢:

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

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

嗨,謝謝,試過你的解決方案並獲得相同數量的查詢。也許我應該把它取到一個json和緩存中。 – user8810516

+0

你可以這樣做,但這並不能真正解決問題。你可以請你的代碼發佈你的'類別'檢索嗎?使用我上面的代碼可以很好地使用新的symfony安裝。 'leftJoin'是重要的方法! – baris1892