OTOBANK Engineering Blog

オトバンクはコンテンツが大好きなエンジニアを募集しています!

Symfony2で利用されているDoctrineに入門する(前編)

こんにちわ!@mrtryです。

年末年始は北海道へ帰省して、寿司を毎日食べてました。
まつりやという回転寿司が最高なので、北海道へ行く機会があれば、ぜひ!

さて、「Symfony2入門」の6回目の記事です。

今回からは、Symfonyで利用されているORMである Doctrine についてまとめていきたいと思います。
内容としては、Doctrineの紹介から、CRUDをするまでの流れについて書いていきたいと思っています。

以下、今回の記事の目次になります

  • Doctrineとは
  • Doctrineがデータ取得するまでの流れ

Doctrineとは

Doctrineとは、Symfonyで利用されているORMです。
ORM(Object-relational mapping)とは、RDBから取得した情報を、特定のクラスと関連付けてオブジェクト化する仕組みです。
この仕組みにより、RDBのテーブルやSQLをほとんど意識せずに、直接オブジェクトとして保存や取得することができます。

簡単な例

文章だけで説明するのも想像しにくい気がしたので、
Doctrineを利用して、CRUD操作する例を簡略化して紹介します。

RDBにproductというテーブルがあって、カラムにprodut_id name price があったとします。
Doctrineを利用すると、productテーブル の作りを元に、以下のようなProductクラスが作成されます。

class Product
{
    private $productId;
    private $name;
    private $price;
    
    ...
}

このクラスのプロパティを変更し、Doctrineに渡すと、RDBを操作することができます。
これにより、SQLをその都度書く必要がなく、RDBの情報操作をオブジェクト指向的に扱うことができます。

例として、以下のような感じのコードを書くことでCRUDすることができます。
(正しさよりも、まずは雰囲気を掴んでほしいという意図で、実際に必要となるコードの一部を端折っています。)

// create
$product = new Product();
$product->setName('apple');
$product->setPrice(100);

// read
$product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($productId);

// update
$product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($productId);
$product->setPrice(100);

// delete
$product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($productId);
$em->remove($product);

また、今回は紹介しませんが、
Doctrine Query Language(DQL)と呼ばれるQuery Languageも用意されており、
SQLのように、クエリを書いて操作することもできます。

Doctrineがデータを取得するまでの流れ

Doctrineを介して情報取得するまでの流れは、以下のようになっています

  1. アプリからDoctrineを呼び出し、情報取得の依頼をする
  2. RDBの情報が記述されている マッピング定義 を読み込む
  3. DoctrineがRDBにアクセスし、リクエストに対応する情報を取得する
  4. マッピング定義 から、リクエストに対応する エンティティクラス を特定し、読み込む
  5. RDBから取得した情報をプロパティに設定し、インスタンス化する
  6. インスタンス化したエンティティを呼び出し元に返す

この流れの中で重要な要素として、 マッピング定義エンティティクラス のふたつがあります。
それぞれについて、説明します。

マッピング定義

アプリケーション内のクラス、プロパティと、RDBのテーブル、カラムの対応関係を定義しているものです。
ざっくりなイメージとしては、 ER図の内容を設定ファイルとしたもの といった感じです。
この定義を元に、DoctrineはRDBから情報を取得し、エンティティにプロパティを設定します。

エンティティ

Doctrineがマッピング定義を元に取得した情報を格納する入れ物です。
識別子(ID)を持っていて、テーブル内の1レコードに対応しています。
最初の方に書いた例で行くと、Productクラスがエンティティにあたります。

おわりに

Doctrineの紹介と情報を取得するまでの手続きについて紹介しました。
次回は、実際にDoctrineを利用し、CRUDをしてみたいと思います。

また、この記事は、@mrtryの勉強の一環で書いていますので、
お気づきの点などがありましたら、コメント等でご指摘いただければ幸いです!

参考