前回に引き続き、今回は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・データベースにも手を出すかもしれません。
最新の投稿
データベース2015年2月3日Symfony2 Doctrine2の小ネタ(OneToMany,ManyToOneリレーション)
データベース2015年1月28日Symfony2 Doctrine2の小ネタ(OneToOneリレーション)
開発2015年1月21日Symfony2でもデザインパターン(PHPクラス編)
開発2014年11月26日Google検索結果画面にパンくずリストを表示する方法 (リッチスニペット対応)