Symfony-doctrine-orm
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!');
}