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

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

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

TblTicket.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?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文に関しても、記載します。

1
2
3
4
5
6
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

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

$childs

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

ポイントは

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

です。

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

Insert

1
2
3
4
5
6
7
8
9
10
11
12
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はかならず

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

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

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

投稿者プロフィール

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


Time limit is exhausted. Please reload CAPTCHA.