Doctrine orm 原则2-如何从主树型实体设计具有子树型属性的实体

Doctrine orm 原则2-如何从主树型实体设计具有子树型属性的实体,doctrine-orm,tree-structure,Doctrine Orm,Tree Structure,我有一个主实体段,它有一对多的类别,类别有一对多的项目,所以有三级树结构 class Segment { /** * @ORM\Id */ protected $id; /** * @ORM\OneToMany(targetEntity="Category", mappedBy="segment") * @ORM\JoinColumn(name="segment_id", referencedColumnName="id")

我有一个主实体段,它有一对多的类别,类别有一对多的项目,所以有三级树结构

class Segment
{

    /**
     * @ORM\Id
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="segment")
     * @ORM\JoinColumn(name="segment_id", referencedColumnName="id")
     */
    protected $categories;
}  

class Category
{

    /**
     * @ORM\Id
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Segment")
     * @ORM\JoinColumn(name="segment_id", referencedColumnName="id")
     */
    protected $segment;

    /**
     * @ORM\OneToMany(targetEntity="Item", mappedBy="category")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    protected $items;
}

class Item
{

    /**
     * @ORM\Id
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Category")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     */
    protected $category;
}
SQL表

CREATE TABLE segment (
    id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
    name VARCHAR(100) NOT NULL,
)

CREATE TABLE segment_category 
(
    id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
    segment_id INT NOT NULL,
    name VARCHAR(100) NOT NULL,
    FOREIGN KEY(segment_id) REFERENCES segment(id)
)
CREATE TABLE segment_item 
(
    id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
    category_id INT NOT NULL,
    name VARCHAR(100) NOT NULL,
    FOREIGN KEY(category_id) REFERENCES segment_category(id)
)
这是我的实体公司,它有来自细分市场的子细分市场

class Company
{
    /**
     * @ORM\Id
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Segment")
     * -- What here to add? Is this correct ?--
     * @ORM\JoinTable(name="company_segment_linker",
     *      joinColumns={@ORM\JoinColumn(name="company_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id")}
     * )
     */
    protected $segments;
}
确定哪个段(以及类别和项目)属于公司的公司SQL表

CREATE TABLE company_segment_linker 
(
    company_id INT NOT NULL,
    item_id INT NOT NULL,
    FOREIGN KEY(company_id) REFERENCES company(id),
    FOREIGN KEY(item_id) REFERENCES segment_item(id)
) 
段数据结构示例(数字表示ID):

  • seg1
  • 第一类
  • 项目1
  • 项目2
  • 项目3
  • 第二类
  • 项目4
  • 项目5
  • seg2
  • 第三类
  • 项目6
  • 第四类
  • 项目7
  • 项目8
  • 公司com1的子细分市场如下:

    /**
     * Category
     *
     * @ORM\Table(name="category")
     * @ORM\Entity(repositoryClass="Category\Entity\Repository\CategoryRepository")
     */
    
    class Category 
    
    {
    /**
    * @var Integer
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="IDENTITY")
    */
    private $id;
    
    /**
     *@var String
     *@ORM\Column(name="cat_name", type="string", length=60, nullable=false)
     * 
     */
    private $name;
    
    
    /**
     * @ORM\OneToMany(targetEntity="Category\Entity\Category", mappedBy="parent")
     **/
    
    private $children;
    
    /**
     *  @ORM\ManyToOne(targetEntity="Category\Entity\Category", inversedBy="children")
     *  @ORM\JoinColumn(name="parent_id", referencedColumnName="id", unique=false, nullable=true)
     **/
    private $parent;
    
    
    
    public function __construct() {
    
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    
    }
    
  • seg1
  • 第一类
  • 项目2
  • 项目3
  • 第二类
  • 项目5
  • seg2
  • 第四类
  • 项目8
  • 因此,我将只在company_segment_链接器表中存储company fk_id和item fk_id
    公司标识|项目标识
    1 | 2
    1|3
    1|5
    1| 8
    因为从项目表中,我可以引用类别,也可以从类别表中引用段

    我的问题是,在Doctrine2中,是否可以仅从项外键创建子段?如果可以,如何编写注释?或者我必须使用另一种方法来实现这一点? 谢谢你的帮助。
    PS:对不起,我的英文是:/

    对于你的分类类,你可以使用一个类似这样的自引用关联:

    /**
     * Category
     *
     * @ORM\Table(name="category")
     * @ORM\Entity(repositoryClass="Category\Entity\Repository\CategoryRepository")
     */
    
    class Category 
    
    {
    /**
    * @var Integer
    * @ORM\Column(name="id", type="integer")
    * @ORM\Id
    * @ORM\GeneratedValue(strategy="IDENTITY")
    */
    private $id;
    
    /**
     *@var String
     *@ORM\Column(name="cat_name", type="string", length=60, nullable=false)
     * 
     */
    private $name;
    
    
    /**
     * @ORM\OneToMany(targetEntity="Category\Entity\Category", mappedBy="parent")
     **/
    
    private $children;
    
    /**
     *  @ORM\ManyToOne(targetEntity="Category\Entity\Category", inversedBy="children")
     *  @ORM\JoinColumn(name="parent_id", referencedColumnName="id", unique=false, nullable=true)
     **/
    private $parent;
    
    
    
    public function __construct() {
    
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();
    
    }
    
    这将为您创建一个表,您可以通过以下DQL获得树:

     $ql="SELECT  ca.name, c.name AS child_name FROM Category\Entity\Category ca LEFT JOIN ca.children c WHERE ca.parent IS NULL";
        $query = $em->createQuery($ql);
      $categories = $query->getResult();
    

    这是我获取分类和sus分类的方式,它在我的一个模块中很好地完成了工作。我希望这对你有用。