[英]Hierarchal data with Doctrine2 using closure table model
我使用閉包表模型存儲了一些現有數據。 我是Doctrine的新手,並試圖以“Doctrine方式”實現一個Entity,並且不確定如何繼續。 我想要遵循的原則是實體應該只是一個普通的PHP對象,並且應該使用某種注釋來配置父子關聯。
在這篇文章中,我將使用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
我在這里有幾個問題。 首先,這似乎是一種合理的方法/可以用Doctrine實現的東西嗎? 如果沒有,有沒有更好的方法來解決這個問題?
如果這看起來像是一種合理的方法,我想知道怎么去攻擊這個? 我正在尋找我需要放置這些文件的位置/我需要如何設置類與有人給我實際實現。 任何有助於我入門的文檔或示例都將非常感激。 我對Doctrine的經驗非常少 - 希望我在這里不會錯過任何明顯的東西。
我想如果你想構建一個分層數據庫,你應該尋找教義ODM項目。 您想要的所有內容都內置於其中,您可以自定義節點。
有一個mongoDB適配器,你也可以看看DoctrinePHPCR項目,它有幾個數據庫的適配器。
即使您想使用doctrine ORM實現自己的方法,您也可以查看它們的實現,以了解它們的工作原理。 它們具有基於節點的關系,因此您始終可以引用對象中樹中的相鄰節點。
希望有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.