ORM Doctrine 2のカスタムリポジトリ

ほとんどの場合、Yamlベースのドクトリン(XMLまたは注釈)によって生成された標準メソッドは、いくつかの単純なフィルターを使用していくつかのフィールドを取得するのに十分です。 より複雑なクエリの場合は、ネイティブQueryBuilderを使用し、dqlクエリを介してモデルにアクセスする必要があります。 これはすべて、同一のクエリが必要な場合にプロパティが重複する大きなコードの山の結果です。 また、1つの方法でモデルを簡単かつ美しく処理したいのですが。 どうやって? 自分で書きましょう!



カスタムリポジトリ



カスタムリポジトリが役立ちます! つまり、これらのリポジトリの意味は、モデルを操作するためのカスタム(非標準)メソッドを保存することです。 すべてのメソッドは、特定のリポジトリが「ねじ込まれる」モデルごとにEntityManagerを介して利用できます。



リポジトリ自体は、EntityRepositoryクラスの子孫です。 それらを別のフォルダー(リポジトリーなど)およびネームスペース(ネームスペース)に保管することをお勧めします-ネームスペースもリポジトリーにします。



単純なユーザーリポジトリフレームワークの例:

namespace Repositories; use Doctrine\ORM\EntityRepository; use Entities; class UserRepository extends EntityRepository { public function getUserMethod($params) { } }
      
      









プロジェクト構造



より明確にするために、プロジェクトディレクトリのフォルダー構造を定義します。





ドクトリン接続



最初に、教義がクラスを見始めるために、Doctrineの一般的な設定ファイルに別のClassLoaderを登録します。 この場合、構成はcli-config.phpファイルにあります 。 次のコード行を追加します。

 //    define("ROOT_DIR", __DIR__); define("DOCTRINE_DIR", ROOT_DIR."/doctrine"); ... //     ,     require_once DOCTRINE_DIR . '/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php'; //           $classLoader = new ClassLoader('Repositories', ROOT_DIR); $classLoader->register(); ...
      
      







リポジトリをモデルに接続する



モデルとリポジトリの関連付けの場所は、使用するマッパーのタイプ(注釈、YAML、またはXML)によって異なります。 YAMLを使用しているため、クラスの名前とその名前空間を記述するrepositoryClass属性を使用して、YAMLを通じてリポジトリを接続します。

 Entities\ModelName: type: entity repositoryClass: Repositories\UserRepository table: model_table fields: ...
      
      







この例では、このYAMLのアンソロジーを含む生成されたモデルがあると想定しています。

 namespace Entities; use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\EntityRepository; /** * Entities\ModelName * * @Table(name="model_table") * @Entity(repositoryClass="Repositories\UserRepository") */ class ModelName { ... }
      
      







それだけです。 これで、リポジトリに独自のメソッドを記述し、モデルを介してそれらを操作できます。 すべてがシンプルであることが判明しました。





ユーザーの気分モデルに独自のメソッドを書くことに基づいた小さな人生の例。

/Entities/UserMood.php

 namespace Entities; use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\EntityRepository; /** * Entities\UserMood * * @Table(name="b_mood") * @Entity(repositoryClass="Repositories\RUserMood") */ class UserMood { /** * @var integer $ID * * @Column(name="ID", type="integer") * @Id * @GeneratedValue(strategy="IDENTITY") */ private $ID; /** * @var string $ACTIVE * * @Column(name="ACTIVE", type="string", length=1, nullable=false) */ private $ACTIVE; /** * @var string $NAME * * @Column(name="NAME", type="string", length=255, nullable=false) */ private $NAME; /** * @var datetime $DATE_ACTIVE_FROM * * @Column(name="DATE_ACTIVE_FROM", type="datetime", nullable=false) */ private $DATE_ACTIVE_FROM; /** * @var decimal $VALUE * * @Column(name="VALUE", type="decimal", nullable=false) */ private $VALUE; /** * @var integer $USER_ID * * @Column(name="USER_ID", type="integer", length=6, nullable=false) */ private $USER_ID; /** * @var string $UNAUTH_HASH * * @Column(name="UNAUTH_HASH", type="string", length=255, nullable=false) */ private $UNAUTH_HASH; //.....       ,        . //.....    ORM. }
      
      







/yaml/Entities.UserMood.dcm.yml



 Entities\UserMood: type: entity repositoryClass: Repositories\RUserMood table: b_mood fields: ID: id: true type: integer generator: strategy: AUTO ACTIVE: type: string length: 1 nullable: false NAME: type: string length: 255 nullable: false DATE_ACTIVE_FROM: type: datetime nullable: false VALUE: type: decimal nullable: false USER_ID: type: integer length: 6 nullable: false UNAUTH_HASH: type: string length: 255 nullable: false
      
      







/Repositories/RUserMood.php



ここでは、メソッドでEntityManager($ em)がどのように宣言されるかに注意する価値があります。 これは次のように行われます。



 $this->_em
      
      







そして今、私たちのリポジトリ自体のコード:



 namespace Repositories; use Doctrine\ORM\EntityRepository; use Entities; class RUserMood extends EntityRepository { public function getMoodsInDateRange($from, $to, $user = false) { $qb = $this->_em->createQueryBuilder(); $filter[1] = $from; $filter[2] = $to; if (!$user) { $varwhere = $qb->expr()->andX( $qb->expr()->gte('um.DATE_ACTIVE_FROM', '?1'), $qb->expr()->lte('um.DATE_ACTIVE_FROM', '?2') ); } else { $filter[3] = $user; $varwhere = $qb->expr()->andX( $qb->expr()->gte('um.DATE_ACTIVE_FROM', '?1'), $qb->expr()->lte('um.DATE_ACTIVE_FROM', '?2'), $qb->expr()->eq('um.USER_ID', '?3') ); } $qb->add('select', new \Doctrine\ORM\Query\Expr\Select(array('um'))) ->add('from', new \Doctrine\ORM\Query\Expr\From('Entities\UserMood', 'um')) ->add('where', $varwhere) ->add('orderBy', new \Doctrine\ORM\Query\Expr\OrderBy('um.DATE_ACTIVE_FROM', 'DESC')) ->setParameters($filter); return $qb->getQuery(); } }
      
      







以上です! ここで、モデルに目を向けると、メソッドを使用できます。 たとえば、次のように:



 include_once ('../cli-config.php'); $repo = DDB::getEM()->getRepository('Entities\UserMood')->getMoodsInDateRange('2011-05-01 00:00:00', '2011-05-09 23:59:59')->getResult(); print_r($repo);
      
      







ソース





PS


私は特にPHPとDoctrineでORMを積極的に使用し始めたばかりなので、この資料でこの問題に対する100%正しい解決策であると主張することはできません。 みんなありがとう!



All Articles