データベースとドクトリン ORM


あらゆるアプリケーションにとって最も一般的かつ困難なタスクの 1 つは、データベースからデータ情報を読み取って保持することです。 symfony フレームワークはデータベースの使用を必要とするコンポーネントを統合していませんが、Doctrine と呼ばれるサードパーティのクラス ライブラリと緊密に統合されています。 Doctrine の主な目標は、データベースの操作をより簡単かつ柔軟にする強力なツールを提供することです。

この章では、symfony プロジェクトで豊富なデータベース インタラクションを提供するために doctrine を使用する方法を学びます。

Doctrine と symfony は完全に分離されており、それらの使用はオプションです。この章では、オブジェクトをリレーショナル データベース (MySQL、PostgreSQL、Microsoft SQL など) にマップできるようにすることを目的とした Doctrine ORM について説明します。データベースの生のクエリを使用したい場合、これは非常に簡単です。説明については、記事 Doctrine DBAL の使用方法 を参照してください。

Doctrine ODM クラス ライブラリを使用してデータを MongoDB に永続化することもできます。詳細については、DoctrineMongoDBBundle を参照してください。

簡単な例: 製品

Doctrine がどのように機能するかを理解する最も簡単な方法は、実際のアプリケーションを確認することです。このセクションでは、データベースを構成し、Product オブジェクトを作成し、それをデータベースに保存してから取得する必要があります。

データベースの構成

実際に開始する前に、データベース接続情報を構成する必要があります。慣例により、情報のこの部分は通常、app/config/parameters.yml ファイルで構成されます:

# app/config/parameters.ymlparameters:
    database_host:      localhost
    database_name:      test_project
    database_user:      root
    database_password:  password
 # ...


#から 設定を定義するためのパラメータ.yml は単なる慣例です。 Doctrine を設定するとき、そのファイルで定義されたパラメータはメイン設定ファイルによって参照されます:

# app/config/config.ymldoctrine:
    dbal:
        driver:   pdo_mysql
        host:     "%database_host%"
        dbname:   "%database_name%"
        user:     "%database_user%"
       password: "%database_password%"
<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:doctrine="http://symfony.com/schema/dic/doctrine"           xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/doctrine        http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">     <doctrine:config>
        <doctrine:dbal                driver="pdo_mysql"                host="%database_host%"                dbname="%database_name%"                user="%database_user%"                password="%database_password%" />
    </doctrine:config></container>
// app/config/config.php$configuration->loadFromExtension('doctrine', array(
    'dbal' => array(
        'driver'   => 'pdo_mysql',
        'host'     => '%database_host%',
        'dbname'   => '%database_name%',
        'user'     => '%database_user%',
        'password' => '%database_password%',
    ),));

データベース情報を別のファイルに分割することで、サーバーごとに異なるバージョンを簡単に保存できます。たとえば、Apache の構成情報と同様に、データベース構成 (または機密情報) をプロジェクトの外部に簡単に保存することもできます。詳細については、サービス コンテナの外部パラメータを設定する方法を参照してください。

これで Doctrine がデータベースに接続できるようになりました。次のコマンドで空の test_project データベースを自動的に生成できます:

$  php bin/console doctrine:database:create

データベースを UTF8 に設定します

Symfony プロジェクトの開始後、経験豊富なプログラマーが犯しやすい間違いは、データベースのデフォルトの文字セットと照合順序 (文字セットと照合順序) の設定を忘れることです。最終的には、データベースのデフォルトの大部分であるラテン語型になります。初めて操作するときは覚えているかもしれませんが、その後の開発で関連する一般的なコマンドを 2 行入力すると、完全に忘れてしまいます。

$  php bin/console doctrine:database:drop --force
$  php bin/console doctrine:database:create

UTF8 を MySQL のデフォルト文字セットとして設定するのは、単に次のように設定するだけです。ファイル (通常は my.cnf ファイル) に数行のコードを追加します。

[mysqld]#Version 5.5.3 introduced "utf8mb4", which is recommendedcollation-server     = utf8mb4_general_ci # Replaces utf8_general_cicharacter-set-server = utf8mb4            # Replaces utf8

生成される SQL で正しい文字セットが使用されるように、Doctrine のデフォルトの文字セットを変更することもできます。

# app/config/config.ymldoctrine:
    dbal:
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci
<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:doctrine="http://symfony.com/schema/dic/doctrine"           xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/doctrine        http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">     <doctrine:config>
        <doctrine:dbal                charset="utf8mb4">
            <doctrine:default-table-option name="charset">utf8mb4</doctrine:default-table-option>
            <doctrine:default-table-option name="collate">utf8mb4_unicode_ci</doctrine:default-table-option>
        </doctrine:dbal>
    </doctrine:config></container>
// app/config/config.php$configuration->loadFromExtension('doctrine', array(
    'dbal' => array(
        'charset' => 'utf8mb4',
        'default_table_options' => array(
            'charset' => 'utf8mb4'
            'collate' => 'utf8mb4_unicode_ci'
        )
    ),));

Mysql の uft8 文字セットは 4 バイトの Unicode 文字と互換性がなく、文字列内にそのような文字が存在するとクリアされるため、使用しないことをお勧めします。ただし、この状況は修正されています。新しい utf8mb4 文字セットを参照してください。

SQLite をデータベースとして使用する場合は、パス オプションでデータベース パスを設定します。

# app/config/config.ymldoctrine:
    dbal:
        driver: pdo_sqlite
        path: "%kernel.root_dir%/sqlite.db"
        charset: UTF8
<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:doctrine="http://symfony.com/schema/dic/doctrine"           xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/doctrine        http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">     <doctrine:config>
        <doctrine:dbal                driver="pdo_sqlite"                path="%kernel.root_dir%/sqlite.db"                charset="UTF-8" />
    </doctrine:config></container>
// app/config/config.php$container->loadFromExtension('doctrine', array(
    'dbal' => array(
        'driver'  => 'pdo_sqlite',
        'path'    => '%kernel.root_dir%/sqlite.db',
        'charset' => 'UTF-8',
    ),));

エンティティの作成class

いくつかの製品を表示する必要があるプログラムを構築しているとします。 Doctrine やデータベースについて考えなくても、これらの製品を表すには Product オブジェクトが必要であることはすでにわかっています。このクラスを AppBundle の Entity ディレクトリに作成します。

// src/AppBundle/Entity/Product.phpnamespace AppBundle\Entity; class Product{
    private $name;
    private $price;
    private $description;}

このクラス - 多くの場合「エンティティ」と呼ばれ、データを保持する基本クラス - これはシンプルで、プログラムで必要な製品のビジネス ニーズを満たします。このクラスはまだデータベースに保存できません。これは単なる単純な PHP クラスです。

Doctrine の背後にある概念を学習したら、Doctrine にエンティティ クラスを作成させることができます。エンティティの作成に役立つ対話型の質問がいくつか表示されます:

$  php bin/console doctrine:generate:entity

マッピング情報の追加

Doctrine を使用すると、単にスカラー データの行を配列に取り込むのではなく、より興味深い方法でデータベースを使用できます。 Doctrine を使用すると、データベースから object 全体を取得し、同時にオブジェクト全体をデータベースに保存できます。 Doctrine でこれを実現するには、データテーブルを特定の PHP クラスに マップ する必要があり、それらのテーブルの列を対応する PHP クラスの特定の属性にマップする必要があります。

1466153595_56497_19601_doctrine_image_1.png

このマッピング情報を「ミートデータ」の形式で提供する必要があります。Doctrine に Product クラスと プロパティを 特定のデータ テーブルにマッピングする方法。このメタデータは、YAML、XML などのさまざまな形式で指定することも、DocBlock アノテーション (アノテーション: アノテーション) を通じて Product クラスに直接定義することもできます。バンドルは 1 つのメタデータ定義形式のみを受け入れることができます。たとえば、YAML メタデータ定義と、アノテーションが追加された PHP エンティティ クラスを混在させることはできません。

#テーブル名はオプションです。省略した場合、エンティティ クラスの名前に自動的に依存します。

Doctrine では、それぞれ独自の設定を持つ幅広いフィールド タイプから選択できます。利用可能なフィールド タイプの詳細については、「Doctrine フィールド タイプ リファレンス」を参照してください。

Doctrine 公式ドキュメント Basic Mapping Documentation を参照して、マッピングに関するすべての詳細を学ぶこともできます。注釈を使用する場合は、すべての注釈に

ORM\
(例:
ORM\Column(...)

) を追加する必要がありますが、これは Doctrine ドキュメントには記載されていません。また、use Doctrine\ORM\Mapping as ORM; 宣言を含める必要があります。これにより、import (インポート) ORM アノテーション プレフィックスを実行できます。

エンティティ クラス名 (またはそのプロパティ) は SQL 予約キーワード (
group
など) でもあることに注意してください。ユーザー番号 ## )。たとえば、エンティティ クラス名が

Group の場合、デフォルトではテーブル名は group になり、一部のデータベース エンジンで SQL エラーが発生する可能性があります。これらの名前を正しく回避する方法については、予約済み SQL キーワードのドキュメントを参照してください。オプションで、データベースのスキーマを任意に選択し、それを別のテーブル名または列名に簡単にマップできます。 「データベースおよびプロパティ マッピングのクラスの作成」ドキュメントを参照してください。

アノテーションを使用する他のライブラリまたはプログラム (Doxygen など) を使用する場合、@IgnoreAnnotation アノテーションをクラスに追加して、Symfony がどのアノテーションを無視するかを示す必要があります。

たとえば、@fn アノテーションが例外をスローしないようにするには、次のアノテーションを追加します。

// src/AppBundle/Entity/Product.phpnamespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /**
 * @ORM\Entity
 * @ORM\Table(name="product")
 */class Product{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;     /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;     /**
     * @ORM\Column(type="decimal", scale=2)
     */
    private $price;     /**
     * @ORM\Column(type="text")
     */
    private $description;

エンティティを作成した後、次のコマンドを使用してマッピングを確認する必要があります:

# src/AppBundle/Resources/config/doctrine/Product.orm.ymlAppBundle\Entity\Product:
    type: entity
    table: product
    id:
        id:
            type: integer
            generator: { strategy: AUTO }
    fields:
        name:
            type: string
            length: 100
        price:
            type: decimal
            scale: 2
        description:
            type: text

ゲッターとセッターの生成

##Doctrine はその方法を認識しましたが、

Product オブジェクトをデータベースに保存しますが、クラス自体にはまだ本当の目的がありません。 Productprivate プロパティを持つ通常の PHP クラスであるため、public ゲッター メソッドとセッター メソッド (getName()# など) を作成する必要があります # #, setName($name)) を使用して、プログラムの他の部分にあるプロパティ (プロパティは保護されています) にアクセスします。幸いなことに、次のコマンドを使用すると、これらのテンプレート化されたメソッドを自動的に生成できます。

<!-- src/AppBundle/Resources/config/doctrine/Product.orm.xml --><?xml version="1.0" encoding="UTF-8" ?><doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                  xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping        http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">     <entity name="AppBundle\Entity\Product" table="product">        <id name="id" type="integer">            <generator strategy="AUTO" />        </id>        <field name="name" type="string" length="100" />        <field name="price" type="decimal" scale="2" />        <field name="description" type="text" />    </entity></doctrine-mapping>
このコマンドにより、

Product

クラスのすべてのゲッターとセッターが確実に生成されます。これは安全なコマンド ラインです。複数回実行でき、存在しないゲッターとセッターのみが生成されます (つまり、既存のメソッドは置き換えられません)。

重要なヒント

次の文は非常に奥深く、Doctrine を効果的に使用するための鍵となります。誰もがそれをしなければなりません。

Doctrine エンティティ ジェネレーターは単純なゲッター/セッターを生成することを覚えておいてください。生成されたメソッドを確認し、必要に応じてアプリケーションのニーズを満たすロジックを追加する必要があります。

doctrine:generate:entities の詳細

doctrine:generate:entities

コマンドの使用

    エンティティ クラスでゲッターとセッターを生成;
  • エンティティ クラスで構成
  • @ORM\ Entity(repositoryClass ="...")

    アノテーションの場合、対応するリポジトリ クラスを生成します;

  • 1:n または n:m に適したコンストラクターを生成します。
doctrine:generate:entities

このコマンドは、元の Product.php ファイルのバックアップを保存し、Product という名前を付けます。 php~。このファイルにより、「クラスを再宣言できません」エラーが発生する場合があります。安全に取り外すことができます。 –no-backup オプションを使用して、これらのバックアップ ファイルが生成されないようにすることもできます。 このコマンドは

必要ないことに注意してください(場合によっては)。ゲッターとセッターを手動で作成することもできます。これらのメソッドの作成は開発中の一般的なタスクであるため、このオプションは時間を節約するためにのみ存在します。

バンドルまたはエンティティ名前空間 (Doctrine マッピング情報を含む任意の PHP クラス) 内のすべての既知のエンティティのゲッターとセッターを生成することもできます。

/**
 * @IgnoreAnnotation("fn")
 */class Product// ...

データ テーブル/スキーマの作成

これで、マッピング情報を含む動作する Product クラスが完成したので、Doctrine はそれを永続化する方法を正確に認識します。もちろん、ライブラリには対応する product データ テーブルがまだありません。幸いなことに、Doctrine はすべてのデータテーブルを自動的に作成できます。これを行うには、次のコマンドを実行します。

$  php bin/console doctrine:schema:validate

真剣に言うと、このコマンドは驚くほど強力です。データベース が理論的にどのように見えるか (エンティティのマッピング情報に基づいて) 実際にどのように見えるか を比較し、データベース スキーマを更新するために必要な SQL ステートメントを実行します。 から はどのように見えるかです。つまり、「マッピング メタデータ」を含む新しいプロパティを Product に追加してこのタスクを実行すると、必要な「ALTER TABLE」ステートメントが既存のテーブルに実行されます。その新しい列を に追加します。製品テーブル。

この機能を活用するより良い方法は、

migrations を使用することです。これにより、これらの SQL ステートメントを生成し、それらを移行クラスに保存し、安全かつ確実に更新できるように実行できます。実稼働環境でのデータベース スキーマの変更を追跡します。

データベース移行を利用するかどうかに関係なく、

doctrine:schema:update コマンドは開発環境での使用にのみ適しています。運用環境では使用しないでください。

これで、指定したメタデータと一致する列を含む、完全に機能する製品テーブルがデータベースに作成されました。

データベースへの永続オブジェクト

これで、Product エンティティとそれにマップされた製品データベース テーブルが完成しました。データをデータベースに永続化できます。コントローラーの内部は非常にシンプルです。次のメソッドをバンドルの DefaultController に追加します。

Product エンティティを対応する product テーブルにマップしたので、Product オブジェクトをデータベースに永続化する準備が整いました。 。コントローラー内部は非常にシンプルです。次のメソッドをバンドルの DefaultController:

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

に追加します。このルーチンに従っている場合は、ルートを作成し、このアクションが実行されることを確認するためにルートを作成する必要があります。

この例は、コントローラーでの Doctrine の getDoctrine() メソッドの使用を示しています。これは、doctrine サービスを簡単に削除する方法です。このサービスをサービスに挿入すると、どこでも doctrine を使用できます。サービスの作成の詳細については、「サービス コンテナ」を参照してください。

前の例を詳しく見てみましょう:

  • 行 10 ~ 13 はここでインスタンス化され、他の通常の PHP オブジェクトと同様に動作します。 $product オブジェクトも同様に使用します。
  • 15 行目 この行は、データベースの永続化 (アノテーション: 書き込み) と物体を取り出すこと。
  • 行 18
  • persist($product) は、Doctrine に $product オブジェクトを「管理」するよう指示するために呼び出されます。 それはデータベースへのリクエストをトリガーしませんでした。 行 21
  • flush() メソッドが呼び出されると、Doctrine は管理するすべてのオブジェクトを走査して、データベースに永続化する必要があるかどうかを判断します。この例では、$product オブジェクトのデータがデータベースに存在しないため、エンティティ マネージャーは INSERT リクエストを実行して、 に新しい行を作成する必要があります。製品テーブル。
実際、Doctrine は管理対象エンティティをすべて認識しているため、
flush()
メソッド Set (changeset) を呼び出すとすべての変更が計算されます。ステートメントを正しい順序で実行します。キャッシュされた準備済みステートメントを利用して、パフォーマンスをわずかに向上させます。たとえば、合計 100 個の

Product オブジェクトを永続化して flush() メソッドを呼び出す場合、Doctrine は単一の準備構文オブジェクトを使用して 100 個の オブジェクトを実行します。 質問を挿入してください。

flush()
呼び出しが失敗すると、

Doctrine\ORM\ORMException 例外がスローされます。 トランザクションと同時実行性を参照してください。

オブジェクトの作成時と更新時のワークフローは同じです。次のセクションでは、レコードがデータベースにすでに存在する場合に、Doctrine がどのようにして自動的に Update ステートメントを発行するかを見ていきます。

Doctrine は、テスト データ (つまり、「フィクスチャ データ」、固定データ) をプログラムでプロジェクトにロードできるクラス ライブラリを提供します。詳細については、DoctrineFixturesBundle を参照してください。

データベースからのオブジェクトの取得

データベースからのオブジェクトの取得はさらに簡単です。たとえば、次のようなルーティングを構成するとします。製品の id を使用して、特定の Product オブジェクトを表示します:

# generates all entities in the AppBundle# 生成AppBundle下的全部entities$  php bin/console doctrine:generate:entities AppBundle
# generates all entities of bundles in the Acme namespace
# 生成Acme命名空间下的bundles的全部entities
$  php bin/console doctrine:generate:entities Acme

@ParamConverter ショートカット アノテーションを使用できます。書き込みは必要ありません。同じ機能を実現するための任意のコード。詳細については、FrameworkExtraBundle を参照してください。

特定の種類のオブジェクトをクエリする場合は、常にその「リポジトリ」を使用します。リポジトリは、その特定のクラスからエンティティを取得することを支援することだけを行う PHP クラスと考えることができます。エンティティクラスの場合、その宝庫にアクセスするには、次を渡します:

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

appBundle:Product は、Doctrine のどこでも使用して、エンティティクラスの FQCN クラスを置き換えることができるショートカット メソッドです。エンティティ クラス名 (AppBundle\Entity\Product など)。エンティティがバンドルの Entity 名前空間に保存されている限り、機能します。

Repository オブジェクトを取得すると、そのオブジェクトのすべての便利なメソッドにアクセスできるようになります。

// src/AppBundle/Controller/DefaultController.php // ...use AppBundle\Entity\Product;use Symfony\Component\HttpFoundation\Response; // ...public function createAction(){
    $product = new Product();
    $product->setName('Keyboard');
    $product->setPrice(19.99);
    $product->setDescription('Ergonomic and stylish!');     $em = $this->getDoctrine()->getManager();     // tells Doctrine you want to (eventually) save the Product (no queries yet)
    // 告诉Doctrine你希望(最终)存储Product对象(还没有语句执行)
    $em->persist($product);     // actually executes the queries (i.e. the INSERT query)
    // 真正执行语句(如,INSERT 查询)
    $em->flush();     return new Response('Saved new product with id '.$product->getId());}

もちろん、複雑なクエリを使用することもできます。「オブジェクト クエリ」セクションを参照してください。

findBy メソッドと findOneBy メソッドを効果的に使用して、複数の条件に基づいてオブジェクトを簡単に取得することもできます。

public function showAction($productId){
    $product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($productId);     if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$productId
        );
    }     // ... do something, like pass the $product object into a template
    // ... 做一些事,比如把 $product 对象传入模板}

任意のページをレンダリングすると、Web デバッグ ツールバーの右下隅に多数のクエリが表示されます。

1466160351_18163_67861_doctrine_web_debug_toolbar (1).png

#アイコンをクリックすると、プロファイラーが開き、生成された正確なクエリが表示されます。

ページのクエリが 50 を超えると、アイコンが黄色に変わります。これは、何かが正しくないことを示しています。

オブジェクトの更新

Doctrine からオブジェクトを取得したら、それを更新するのは簡単です。プロダクト ID をコントローラーの更新アクションにマップするルートがあるとします。

$repository = $this->getDoctrine()
    ->getRepository('AppBundle:Product');

オブジェクトの更新には 3 つのステップが含まれます:

  1. Doctrine からオブジェクトを取得します;
  2. オブジェクトを変更します;
  3. エンティティ マネージャーの flush() メソッドを呼び出します。

$em->persist($product) の呼び出しは不要であることに注意してください。このメソッドは Doctrine に $product オブジェクトを管理または「監視」するよう指示するだけであることを思い出してください。ここでは、$product オブジェクトをすでに取得しているため、すでに管理されています。

オブジェクトの削除

オブジェクトの削除は非常に似ていますが、エンティティ マネージャーから remove() を呼び出す必要があります。

$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
// query for a single product by its primary key (usually "id")// 通过主键(通常是id)查询一件产品
$product = $repository->find($productId); // dynamic method names to find a single product based on a column value// 动态方法名称,基于字段的值来找到一件产品$product = $repository->findOneById($productId);$product = $repository->findOneByName('Keyboard');
// dynamic method names to find a group of products based on a column value
// 动态方法名称,基于字段值来找出一组产品$products = $repository->findByPrice(19.99); 
// find *all* products / 查出 *全部* 产品$products = $repository->findAll();

ご想像のとおり、remove() メソッドは、指定されたエンティティをデータベースから削除することを Doctrine に通知します。実際の DELETE クエリは、flush() メソッドが呼び出されるまで実際には実行されません。

オブジェクト クエリ

リポジトリ オブジェクトを使用して、何も作業せずにいくつかの基本的なクエリを実行できる方法を見てきました:

$repository = $this->getDoctrine()->getRepository('AppBundle:Product'); // query for a single product matching the given name and price// 查询一件产品,要匹配给定的名称和价格$product = $repository->findOneBy(
    array('name' => 'Keyboard', 'price' => 19.99)); // query for multiple products matching the given name, ordered by price// 查询多件产品,要匹配给定的名称和价格$products = $repository->findBy(
    array('name' => 'Keyboard'),
    array('price' => 'ASC'));

もちろん、Doctrine では Doctrine Query Language (DQL) を使用して複雑なクエリを作成することもできます。DQL は SQL に似ていますが、1 つ以上のエンティティ クラス オブジェクト (product# など) をクエリするために使用される点が異なります。 ##) 、SQL はデータ テーブル (product など) の行をクエリします。

Doctrine でクエリを実行する場合、主に 2 つのオプションがあります。純粋な Doctrine クエリ (DQL) を作成するか、Doctrine のクエリ ビルダーを使用するかです。

オブジェクト クエリに DQL を使用する

価格が

19.99 より高い製品をクエリし、低価格から高価格の順に並べ替えるとします。 。 Doctrine のネイティブ SQL に似た構文である DQL を使用して、このシナリオのクエリを構築できます。

public function updateAction($productId){
    $em = $this->getDoctrine()->getManager();
    $product = $em->getRepository('AppBundle:Product')->find($productId);     if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$productId
        );
    }     $product->setName('New product name!');
    $em->flush();     return $this->redirectToRoute('homepage');}

SQL の記述に慣れている場合は、DQL も非常に自然です。それらの最大の違いは、データ テーブルの行ではなく、「PHP オブジェクトの選択」という観点から考える必要があることです。このため、

AppBundle:Product から開始し、entity (AppBundle\Entity\Product クラスのオプションのショートカット) を選択します。 、エンティティに p というエイリアスを付けます。

setParameter()

メソッドに注意してください。 Doctrine を使用する場合、SQL インジェクション攻撃を防ぐため、「プレースホルダー」 (上記の例では :price) を介して任意の外部値を設定することをお勧めします。

getResult() このメソッドは結果配列を返します。結果を取得するには、getSingleResult() (このメソッドは結果がない場合に例外をスローします) または getOneOrNullResult():

$em->remove($product);$em->flush();

DQL 構文を使用できます。信じられないほど強力です。エンティティ (関係については後で説明します)、グループなどの間の結合を簡単に行うことができます。詳細については、Doctrine Query Language ドキュメントを参照してください。

Doctrine の Query Builder をオブジェクト クエリに使用する

DQL で大きな文字列を記述する代わりに、非常に便利な QueryBuilder オブジェクトを使用してその文字列を構築できます。これは、クエリが動的な条件に依存する場合に便利です。接続文字列が増大し続けると、DQL コードがますます読みにくくなるからです。

$repository = $this->getDoctrine()->getRepository('AppBundle:Product'); $product = $repository->find($productId);$product = $repository->findOneByName('Keyboard');

QueryBuilder オブジェクトには、必要なメソッドがすべて含まれています。 getQuery() メソッドを呼び出すと、クエリ ビルダーは、要求された結果セットを取得するために使用できる標準の Query オブジェクトを返します。

クエリ ビルダー詳細については、Doctrine の クエリ ビルダー ドキュメントを参照してください。

カスタム クエリをリポジトリ クラスに編成する

前述のクエリはすべて、コントローラーに直接書き込まれます。ただし、プログラムを編成するために、Doctrine はすべてのクエリ ロジックを中央の場所に保存できる専用のリポジトリ クラスを提供します。詳細については、

参照 カスタム リポジトリ クラスの作成方法を参照してください。

設定

Doctrine は高度に設定可能ですが、これらのオプションは気にしないかもしれません。 Doctrine の設定情報については、設定リファレンスを参照してください。

Doctrine フィールド タイプ リファレンス ¶

Doctrine には、利用可能な多数のフィールド タイプが付属しています。使用するデータベースに関係なく、それぞれが PHP データ型を特定のフィールド型にマッピングできます。フィールド タイプごとに、Column をさらに構成して、lengthnullable の動作、name またはその他のオプションを設定できます。使用可能なフィールド タイプのリストについては、マッピング タイプのドキュメントを参照してください。

関連付けと関係 ¶

Doctrine は、データベースの関係 (関連付けとも呼ばれます) を管理するために必要なすべての機能を提供します。詳細については、「Doctrine Association/Relations の使用方法」を参照してください。

概要 ¶

Doctrine を使用すると、データベースの永続性は二の次でありながら、オブジェクトとそれをプログラムに適用する方法に集中できます。これは、Doctrine では任意の PHP オブジェクトを使用してデータを保存でき、「メタデータ マッピング」情報に依存してオブジェクトのデータを特定のデータ テーブルにマッピングできるためです。

Doctrine には、リレーションシップ、複雑なクエリ、イベント監視など、学習を待つ多くの強力な機能があります。