Symfony2 Doctrine2の小ネタ(OneToMany,ManyToOneリレーション)

前回に引き続き、今回はSymfony2のデータベース処理に使われるDoctrine2のリレーションのうちOneToManyとManyToOneを説明しましょう。
詳しい中身はこちらの英語ドキュメントを参照しましょう。
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html

前回と同じエンティティを用います、不必要な部分に関しては省略します。

TblTicket.php

<?php
namespace Hoge\FugaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 *
 * @ORM\Table(name="tbl_ticket")
 * @ORM\Entity(repositoryClass="Hoge\FugaBundle\Repository\TicketRepository")
 */
class TblTicket
{
    /**
     * @var bigint $id
     *
     * @ORM\Column(name="id", type="bigint", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="TblTicket", inversedBy="childs")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
     */
    private $parent;

    /**
     * @ORM\OneToMany(targetEntity="TblTicket", mappedBy="parent")
     */
    private $childs;

     /**
     * @ORM\OneToOne(targetEntity="TblTicketData", mappedBy="ticket", cascade={"persist"})
     */
    private $data;


    public function __construct(){
        $this->childs = new ArrayCollection();
    }
    
    /**
     * Get id
     *
     * @return bigint
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * get parent
     * @return TblTicket
     */
    public function getParent ()
    {
        return $this->parent;
    }

    /**
     * setparent
     * @param TblTicket $parent
     * @return TblTicket
     */
    public function setParent ($parent)
    {
        $this->parent = $parent;
        return $this;
    }

    /**
     * get data
     * @return TblTicketData
     */
    public function getData ()
    {
        return $this->data;
    }

    /**
     * set data
     * @param TblTicketData $parentData
     * @return TblTicketData
     */
    public function setParentData ($parentData)
    {
        $this->parentData = $parentData;
        return $this;
    }




    /**
     * Add childs
     *
     * @param TblTicket $childs
     */
    public function addChild(TblTicket $childs)
    {
        $this->childs[] = $childs;
    }

    /**
     * Get childs
     *
     * @return Doctrine\Common\Collections\Collection
     */
    public function getChilds()
    {
        return $this->childs;
    }

 
}

今回はTblTicketData.php は使う必要がないので、省略します。
前回同様SQL文に関しても、記載します。

CREATE TABLE tbl_ticket (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  parent_id bigint(20) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY IDX_1A06C41C727ACA70 (parent_id),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ここから、判断できるポイントを列挙していきましょう。

  • tbl_ticketは木構造となっており、親チケットを自身のテーブルに持っている
  • tbl_ticketは一番親のチケットを判断するために、parent_idにNullを許可している

では、エンティティの中身を見てみましょう

$parent

@ORM\ManyToOne(targetEntity="TblTicket", inversedBy="childs")
@ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)

$childs

@ORM\OneToMany(targetEntity="TblTicket", mappedBy="parent")

ポイントは

  • 所属する側のデータ($parent)にはManyToOne inversedByとJoinColumnを付与する
  • 所属される側のデータ($childs)にはOneToMany mappedByを付与する
  • JoinColumnによってTblTicketのparent_idとTblTicketのid間のリレーションが作られる
  • nullable=trueによって、Parentの存在を保障しない

です。

では、続いて、このデータのInsertに関して考えてみましょう。

Insert

public function createAction()
{
    $ticket = new TblTicket();
    $child  = new TblTicket();
    $child->setParent($ticket);
    $em = $this->getDoctrine()->getEntityManager();
    $em->persist($ticket);
    $em->persist($child);
    $em->flush();

    return new Response('Created ticket');
}

もしもチケットに対して親チケットを設定する必要があれば、setParentを呼び出しましょう。

注意!

OneToManyによって設定された、Attributeはかならず

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

によって初期化されなければいけません。

では今日はこの辺で、失礼いたします。

投稿者プロフィール

開発 アルバイト
中の人には主に、
PHP・Symfony2系の人と
Ruby・Rails系の人がいます。
ときどきJavascript・データベースにも手を出すかもしれません。

コメントを残す

メールアドレスが公開されることはありません。

Time limit is exhausted. Please reload CAPTCHA.