Иерархические данные с Doctrine2 с использованием модели таблицы закрытия

У меня есть некоторые существующие данные, хранящиеся с использованием модель закрывающего стола. Я новичок в Доктрине, и пытаюсь реализовать сущность для этого «Пути доктрины», и не совсем уверен, как действовать дальше. Философия, которой я пытаюсь следовать, заключается в том, что Entity должен быть просто старым PHP-объектом, и что для настройки ассоциаций родитель-потомок необходимо использовать какую-то аннотацию.

В этом посте я буду использовать категорию в качестве примера сущности. Вот что я представляю, как выглядит сущность:

<?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 — надеюсь, я не пропускаю ничего очевидного.

3

Решение

Я думаю, что если вы хотите построить иерархическую базу данных, вы должны искать проект доктрины ODM. Все, что вы хотите, встроено в это, и вы можете настроить свой узел.

Есть адаптер mongoDB, а также вы можете взглянуть на проект DoctrinePHPCR, в котором есть адаптеры для нескольких баз данных.

Даже если вы хотите реализовать свой собственный подход с использованием доктрины ORM, вы можете посмотреть на их реализации, чтобы понять, как они работают. Они имеют отношения на основе узлов, поэтому у вас всегда есть ссылки на соседние узлы в дереве вашего объекта.

Надеюсь, это поможет.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]