Symfony-doctrine-orm

提供:Dev Guides
移動先:案内検索

symfony-Doctrine ORM

Symfony Webフレームワークでは、モデルが重要な役割を果たします。 それらはビジネスエンティティです。 これらは顧客から提供されるか、バックエンドデータベースから取得され、ビジネスルールに従って操作され、データベースに保持されます。 これらは、ビューによって表示されるデータです。 この章では、モデルとバックエンドシステムとの相互作用について学習します。

データベースモデル

モデルをバックエンドリレーショナルデータベースアイテムにマップして、モデルを安全かつ効率的に取得して永続化する必要があります。 このマッピングは、オブジェクトリレーショナルマッピング(ORM)ツールを使用して実行できます。 Symfonyは、サードパーティのPHPデータベースORMツールである Doctrine とSymfonyを統合する別個のバンドル DoctrineBundle を提供します。

ドクトリンORM

デフォルトでは、Symfonyフレームワークはデータベースを操作するコンポーネントを提供しません。 しかし、それは Doctrine ORM と密接に統合します。 Doctrineにはデータベースストレージとオブジェクトマッピングに使用されるいくつかのPHPライブラリが含まれています。

次の例は、Doctrineの機能、データベースの設定方法、データの保存および取得方法を理解するのに役立ちます。

Doctrine ORMの例

この例では、最初にデータベースを構成し、Studentオブジェクトを作成してから、その中でいくつかの操作を実行します。

これを行うには、次の手順に従う必要があります。

ステップ1:Symfonyアプリケーションを作成する

次のコマンドを使用して、Symfonyアプリケーション dbsample を作成します。

symfony new dbsample

ステップ2:データベースを構成する

通常、データベース情報は「app/config/parameters.yml」ファイルで設定されます。

ファイルを開き、次の変更を追加します。

*parameter.yml*
parameters:
   database_host: 127.0.0.1
   database_port: null
   database_name: studentsdb
   database_user: <user_name>
   database_password: <password>
   mailer_transport: smtp
   mailer_host: 127.0.0.1
   mailer_user: null
   mailer_password: null
   secret: 037ab82c601c10402408b2b190d5530d602b5809

   doctrine:
      dbal:
      driver:   pdo_mysql
      host:     '%database_host%'
      dbname:   '%database_name%'
      user:     '%database_user%'
      password: '%database_password%'
      charset: utf8mb4

これで、Doctrine ORMはデータベースに接続できます。

ステップ3:データベースを作成する

次のコマンドを発行して、「studentsdb」データベースを生成します。 このステップはDoctrine ORMでデータベースをバインドするために使用されます。

php bin/console doctrine:database:create

コマンドを実行すると、空の「studentsdb」データベースが自動的に生成されます。 画面に次の応答が表示されます。

Created database `studentsdb` for connection named default

ステップ4:地図情報

マッピング情報は「メタデータ」に他なりません。 Studentクラスとそのプロパティが特定のデータベーステーブルにどのようにマッピングされるかをDoctrine ORMに正確に通知するルールのコレクションです。

さて、このメタデータは、YAML、XMLなど、さまざまな形式で指定するか、アノテーションを使用してStudentクラスを直接渡すことができます。 次のように定義されています。

Student.php

ファイルに次の変更を追加します。

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
/* *
  * @ORM\Entity
   * @ORM\Table(name = "students")
*/
class Student {
  /* *
     * @ORM\Column(type = "integer")
 *@ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
   */
   private $id;

  /* *
     * @ORM\Column(type = "string", length = 50)
   */
   private $name;

  /* *
    * @ORM\Column(type = "text")
     */
   private $address;
}

ここでは、テーブル名はオプションです。 テーブル名が指定されていない場合、エンティティクラスの名前に基づいて自動的に決定されます。

ステップ5:エンティティをバインドする

Doctrineはあなたのためにシンプルなエンティティクラスを作成します。 エンティティの構築に役立ちます。

次のコマンドを発行して、エンティティを生成します。

php bin/console doctrine:generate:entities AppBundle/Entity/Student

その後、次の結果が表示され、エンティティが更新されます。

Generating entity "AppBundle\Entity\Student"
   > backing up Student.php to Student.php~
   > generating AppBundle\Entity\Student

Student.php

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
/* *
  * @ORM\Entity
   * @ORM\Table(name="students")
*/
class Student {
  /* *
     * @ORM\Column(type="integer")
 *@ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
   */
   private $id;

  /* *
     * @ORM\Column(type = "string", length = 50)
   */
   private $name;

  /* *
     * @ORM\Column(type = "text")
   */
   private $address;

  /* *
     * Get id
 *
     * @return integer
   */
   public function getId() {
      return $this->id;
   }

  /* *
     * Set name
 *
     * @param string $name
 *
     * @return Student
   */

   public function setName($name) {
      $this->name = $name;
      return $this;
   }

  /* *
     * Get name
 *
     * @return string
   */

   public function getName() {
      return $this->name;
   }

  /**
 *Set address
     *
 *@param string $address
     *
 *@return Student
  */

   public function setAddress($address) {
      $this->address = $address;
      return $this;
   }

  /* *
     * Get address
 *
     * @return string
   */

   public function getAddress() {
      return $this->address;
   }
}

ステップ6:検証のマッピング

エンティティを作成したら、次のコマンドを使用してマッピングを検証する必要があります。

php bin/console doctrine:schema:validate

それは次の結果を生成します-

[Mapping]  OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file

Studentsテーブルを作成していないため、エンティティは同期していません。 次のステップでSymfonyコマンドを使用して、studentsテーブルを作成しましょう。

ステップ7:スキーマを作成する

DoctrineはStudentエンティティに必要なすべてのデータベーステーブルを自動的に作成できます。 これは、次のコマンドを使用して実行できます。

php bin/console doctrine:schema:update --force

コマンドを実行すると、次の応答が表示されます。

Updating database schema...
Database schema updated successfully! "1" query was executed

このコマンドは、データベースの外観と実際の外観を比較し、データベーススキーマをあるべき場所に更新するために必要なSQLステートメントを実行します。

ここで、次のコマンドを使用してスキーマを再度検証します。

php bin/console doctrine:schema:validate

それは次の結果を生成します-

[Mapping]  OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files

ステップ8:ゲッターとセッター

「エンティティのバインド」セクションで見たように、次のコマンドはStudentクラスのすべてのゲッターとセッターを生成します。

$ php bin/console doctrine:generate:entities AppBundle/Entity/Student

ステップ9:オブジェクトをデータベースに永続化する

これで、Studentエンティティを対応するStudentテーブルにマッピングしました。 これで、Studentオブジェクトをデータベースに永続化できるはずです。 バンドルのStudentControllerに次のメソッドを追加します。

StudentController.php

<?php
namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Student;

class StudentController extends Controller {
  /* *
     * @Route("/student/add")
   */
   public function addAction() {
      $stud = new Student();
      $stud->setName('Adam');
      $stud->setAddress('12 north street');
      $doct = $this->getDoctrine()->getManager();

     //tells Doctrine you want to save the Product
      $doct->persist($stud);

     //executes the queries (i.e. the INSERT query)
      $doct->flush();

      return new Response('Saved new student with id ' . $stud->getId());
   }
}

ここでは、ベースコントローラーのgetDoctrine()を介してgetManager()メソッドを使用して、Doctrineマネージャーにアクセスし、Doctrineマネージャーのpersist()メソッドを使用して現在のオブジェクトを永続化します。 * persist()メソッドはコマンドをキューに追加しますが、 flush()*メソッドは実際の作業を行います(学生オブジェクトを保持します)。

ステップ10:データベースからオブジェクトを取得する

StudentControllerで、学生の詳細を表示する関数を作成します。

*StudentController.php*
/* *
  * @Route("/student/display")
*/
public function displayAction() {
   $stud = $this->getDoctrine()
   ->getRepository('AppBundle:Student')
   ->findAll();
   return $this->render('student/displayl.twig', array('data' => $stud));
}

ステップ11:ビューを作成する

表示アクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「displayl.twig」を作成します。 ファイルに次の変更を追加します。

*displayl.twig*
<style>
   .table { border-collapse: collapse; }
   .table th, td {
      border-bottom: 1px solid #ddd;
      width: 250px;
      text-align: left;
      align: left;
   }
</style>

<h2>Students database application!</h2>
<table class = "table">
   <tr>
      <th>Name</th>
      <th>Address</th>
   </tr>
   {% for x in data %}
   <tr>
      <td>{{ x.Name }}</td>
      <td>{{ x.Address }}</td>
   </tr>
   {% endfor %}
</table>

ブラウザでURL「http://localhost:8000/student/display」をリクエストすることで結果を取得できます。

画面に次の出力が生成されます-

ビューの作成

ステップ12:オブジェクトを更新する

StudentControllerのオブジェクトを更新するには、アクションを作成し、次の変更を追加します。

/* *
  * @Route("/student/update/{id}")
*/
public function updateAction($id) {
   $doct = $this->getDoctrine()->getManager();
   $stud = $doct->getRepository('AppBundle:Student')->find($id);

   if (!$stud) {
      throw $this->createNotFoundException(
         'No student found for id '.$id
      );
   }
   $stud->setAddress('7 south street');
   $doct->flush();

   return new Response('Changes updated!');
}

ここで、URL「http://localhost:8000/Student/update/1」をリクエストすると、次の結果が生成されます。

画面に次の出力が生成されます-

オブジェクトの更新

ステップ13:オブジェクトを削除する

オブジェクトの削除も同様であり、エンティティ(doctrine)マネージャーのremove()メソッドを呼び出す必要があります。

これは、次のコマンドを使用して実行できます。

/* *
  * @Route("/student/delete/{id}")
*/
public function deleteAction($id) {
   $doct = $this->getDoctrine()->getManager();
   $stud = $doct->getRepository('AppBundle:Student')->find($id);

   if (!$stud) {
      throw $this->createNotFoundException('No student found for id '.$id);
   }

   $doct->remove($stud);
   $doct->flush();

   return new Response('Record deleted!');
}