2015-06-05 35 views
3

我有一些使用closure table model存儲的現有數據。我對新學說很陌生,並試圖爲這種「主義方式」實施一個實體,但並不確定如何繼續。我試圖遵循的哲學是,實體應該只是一個普通的舊PHP對象,並且應該使用某種註釋來配置父子關聯。使用閉包表模型的Doctrine2的分層數據

在這篇文章中,我將使用Category作爲示例實體。這就是我想象中的實體看起來像:

<?php 

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @ORM\Table(name="categories) 
* @ORM\Entity 
*/ 
class Category 
{ 
    /** 
    * @ORM\Column(name="categoryID", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $categoryID; 

    /** 
    * @ORM\Column(name="title", type="string", length=255) 
    */ 
    protected $title; 

    /** 
    * @MyORM\TreeParent(targetEntity="Category", closureTable="categories_paths", ancestorColumn="ancestorID", descendantColumn="descendantID") 
    */ 
    protected $parent; 

    /** 
    * @MyORM\TreeChildren(targetEntity="Category", closureTable="categories_paths", ancestorColumn="ancestorID", descendantColumn="descendantID") 
    */ 
    protected $children; 

    public function __construct() 
    { 
     $this->children = new ArrayCollection(); 
    } 

    public function getChildren() 
    { 
     return $this->children; 
    } 

    public function addChild(Category $child) 
    { 
     $this->children[] = $children; 
    } 

    public function getParent() 
    { 
     return $this->parent; 
    } 

    public function setParent(Category $parent) 
    { 
     $this->parent = $parent; 
    } 
} 

的封閉表如下所示:

categories_paths(ancestorID, descendantID, pathLength) 

此表基本上是一個連接表 - 它只是存儲的父子關係,所以我不要認爲這裏有一個實體是有意義的,類似於在與@JoinTable創建多對多關係時沒有實體。

我希望能夠用我的實體類像任何其他實體,與人口$parent/$children當我從存儲庫中取出它,當$em->flush()被調用時,已經執行的SQL,以反映新加入的孩子。

SQL的一些例子在這裏使用:

添加一個新的子:

INSERT INTO categories_paths (ancestorID, descendantID, pathLength) 
SELECT a.ancestorID, d.descendantID, a.pathLength+d.pathLength+1 
FROM categories_paths a, categories_paths d 
WHERE a.descendantID = $parentCategoryID AND d.ancestorID = $childCategoryID 

移動子樹到一個新的父:

// Delete all paths that end at $child 
DELETE a FROM categories_paths a 
JOIN categories_paths d ON a.descendantID=d.descendantID 
LEFT JOIN categories_paths x 
ON x.ancestorID=d.ancestorID AND x.descendantID=a.ancestorID 
WHERE d.ancestorID = $subtreeCategoryID and x.ancestorID IS NULL 

// Add new paths 
INSERT INTO categories_paths (ancestorID, descendantID, pathLength) 
SELECT parent.ancestorID, subtree.descendantID, 
     parent.pathLength+subtree.pathLength+1 
FROM categories_paths parent 
JOIN categories_paths subtree 
WHERE subtree.ancestorID = $subtreeCategoryID 
    AND parent.descendantID = $parentCategoryID; 

獲取一個類別的所有子:

SELECT * FROM categories 
JOIN categories_paths cp ON cp.descendantID=categories.categoryID 
WHERE cp.ancestorID = $catogeryID 
AND cp.depth=1 

我在這裏有幾個問題。首先,這看起來像是一種合理的方法/可以用教義實現的東西?如果沒有,是否有更好的方法來解決這個問題?

如果這確實看起來像一個合理的方法,我想知道如何去攻擊這個?我更多地尋找需要放置這些文件的位置/我需要如何設置類,還是有人給我一個實際的實現。任何能夠幫助我開始的文檔或示例都將非常感謝。我對教義幾乎沒有任何經驗 - 希望我在這裏不會錯過任何明顯的東西。

回答

0

我想如果你想建立一個分層數據庫,你應該尋找doctrine ODM項目。所有你想要的東西都是內置的,你可以定製你的節點。

有一個mongoDB適配器,你也可以看看有幾個數據庫適配器的DoctrinePHPCR項目。

即使你想使用doctrine ORM來實現你自己的方法,你也可以看看它們的實現來了解它們是如何工作的。它們具有基於節點的關係,因此您始終可以參考對象中樹中的相鄰節點。

希望有所幫助。