Doctrine 2について
始めに、Doctrine 2についての簡単な紹介を行います。プロジェクトは現在3つのパッケージに分割されています。
- 共通
 - DBAL
 - ORM
 
共通 -他のパッケージで使用される共通コンポーネントが含まれています。
DBAL-データベースアクセス抽象化レイヤー。
ORM-オブジェクトリレーショナルマッピングツール
Doctrine 2には、以前の* Tableおよび* Recordクラスになじみのあるものはありません。 また、モデルクラスがレコードクラスを継承する必要がなくなり、テーブルクラスがDoctrineパッケージからテーブルクラスを継承することも意味します。 代わりに、2つの新しい概念、EntityとEntityManagerが導入されています。 エンティティは、大まかに言って、モデルのオブジェクトであり、EntityManagerは、エンティティオブジェクトをそれぞれ管理できるクラスです。 おもしろいことは、「Entity」は任意のPHPクラスであり、Doctrineパッケージからクラスを継承しないことです。
Doctrine 1では、モデルはYamlファイルで記述されていましたが、現在はYaml、XML、またはDocblockアノテーションを使用できます。 おそらく、PHPDocumentorでメソッドを記述するために、だれでも何らかの形でDocblockアノテーションを使用する必要がありました。 そのため、永続オブジェクトのメタデータを記述することもできます。
例:
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
Copy Source | Copy HTML <?php /** <br/> * @Entity <br/> * @Table(name="my_model") <br/> */ class MyModel { /** <br/> * @Id @Column(name="id", type="integer") <br/> * @GeneratedValue(strategy="AUTO") <br/> */ private $id ; /** <br/> * @Column(name="title", type="string", length=255) <br/> */ private $title ; }
そしてもちろん、あなたはDoctrineのウェブサイトでこれらすべてについてもっと読むことができます
離陸
非常に小さくて非常にシンプルなアプリケーションの例として、Doctrine 2の使用を検討することにしました。 これはReadlaterサービスになり、リンクを保存して後で読むまで延期することができます。 つまり、すべての機能が3つの単純なアクションに削減されます。
- リストリンク
 - リンクを追加
 - リンクを削除
 
しかし、私はすぐに小さな問題に遭遇しました-Doctrine 2とSymfony 2の両方が現在活発に開発されており、安定性の問題はありません。 さらに、すべてが非常に頻繁に変化し、今日動作するものは明日は離陸しないかもしれません。 多くの場合、これらはコードを別のディレクトリに移動するなど、さまざまな小さなものです。 したがって、このアプリケーションでは、使用するライブラリのバージョンを凍結することにしました。 このために、私は取りました:
- symfony-sandbox :すべてが建設中だったサンドボックス
 - symfony :Jonathan Wage開発者Doctrineによるsymfonyのフォーク
 - 教義の移行 :移行
 - 教義 :トランクの教義
 
これらすべてをまとめて、2010年4月18日にすべてのバージョンを元の形式に固定し、アプリケーションと一緒にgithubで共有しました。 あなたが興味を持っているのであれば、それのために行きます。
飛んだ
したがって、最初は構造について簡単に説明します。 この種類のディレクトリについて:
- readlater :-アプリケーションディレクトリ
 -   src 
- アプリケーション :-ここでは、「バンドル」ReadlaterBundleが存在し、一般的にそこにコーディングします。
 - バンドル :-この場合は空です
 - ベンダー :-ここにフレームワークとすべてのライブラリがあります
 
 
構成から始めましょう。 readlater / config / config.ymlに以下を追加します:
Copy Source | Copy HTML
- カーネル。 構成 :〜
 - ウェブ ウェブ :〜
 - ウェブ テンプレート化 :〜
 - 教義。 dbal :
 - default_connection : デフォルト
 - 接続 :
 - デフォルト :
 - ドライバー :PDOMySql
 - dbname :sfbox2
 - ユーザー :ルート
 - パスワード : 123
 - ホスト :localhost
 - event_manager_class :Doctrine \ Common \ EventManager
 - configuration_class :Doctrine \ DBAL \設定
 - 教義。 orm :
 - default_entity_manager : デフォルト
 - cache_driver :配列
 - entity_managers :
 - デフォルト :
 - 接続 : デフォルト
 
doctrine.dbalデータベースへの接続と、Doctrine \ ORMパッケージdoctrine.ormの設定について説明しました
ここではアプリケーションコアの作成については説明しません。symfony-sandboxで行われるものと実質的に変わらないからです。
したがって、 src / Applicationに配置したReadlaterBundleに進み ます 。 バンドルの構造は次のとおりです。
- コントローラー :-ここにコントローラーがあります
 - エンティティ :-ここにエンティティ、モデルクラスがあります
 -   資源 
- config :-ここでの設定
 - ビュー :-ここにテンプレートがあります
 
 
エンティティディレクトリでは、これ以上必要ないため、単一のLinkクラスを作成します。 Doctrine 2はデフォルトでバンドルエンティティディレクトリにエンティティを作成することを提案します。つまり、各バンドルは独自のモデルクラスのセットを持つことができます。 設定として、DoctrineにEntities以外のディレクトリでクラスを検索するように依頼できますが、私はこれを行いません。
Linkクラスのコードは次のとおりです。
Copy Source | Copy HTML
- <?php
 - 名前空間 Application \ ReadlaterBundle \ Entities;
 - Doctrine \ ORM \ EntityRepositoryを使用します。
 - / ** <br/> * @Entity <br/> * @Table(name = "readlater_link") <br/> * /
 - クラスリンク
 - {
 - / ** <br/> * @Id @Column(name = "id"、type = "integer") <br/> * @GeneratedValue(strategy = "AUTO") <br/> * /
 - プライベート $ id ;
 - / ** <br/> * @Column(name = "url"、type = "string"、length = 255) <br/> * /
 - プライベート $ url ;
 - / ** <br/> * @Column(name = "created_at"、type = "datetime") <br/> * /
 - private $ createdAt ;
 - / ** <br/> *コンストラクター <br/> * /
 - パブリック関数 __construct()
 - {
 - $ this-> createdAt = new \ DateTime ();
 - }
 - / ** <br/> *文字列 <br/>へ* /
 - パブリック関数 __toString()
 - {
 - return $ this-> getUrl();
 - }
 - }
 
クラスで3つのフィールドを定義しました。
- $ id-識別子
 - $ url-リンクのURL
 - $ createdAt-追加日
 
また、すでに明確な2つのメソッドも追加しました。 例からわかるように、Docblockを使用してモデルを説明しました。
いくつかのコマンドを実行しました:
readlater/console doctrine:database:create 
      
        
        
        
      
     readlater/console doctrine:generate:entities 
      
        
        
        
      
     readlater/console doctrine:schema:create 
      
        
        
        
      
    
      
      最初のチームはデータベースを作成し、2番目はクラスのメソッドを生成して作業を行い、3番目はデータベースにテーブルを作成します。
次のようになります。
 
      Linkクラスを調べると、少し変更されていることがわかりますが、次のようになります。
Copy Source | Copy HTML
- <?php
 - 名前空間 Application \ ReadlaterBundle \ Entities;
 - Doctrine \ ORM \ EntityRepositoryを使用します。
 - / ** <br/> * @Entity <br/> * @Table(name = "readlater_link") <br/> * /
 - クラスリンク
 - {
 - / ** <br/> * @Id @Column(name = "id"、type = "integer") <br/> * @GeneratedValue(strategy = "AUTO") <br/> * /
 - プライベート $ id ;
 - / ** <br/> * @Column(name = "url"、type = "string"、length = 255) <br/> * /
 - プライベート $ url ;
 - / ** <br/> * @Column(name = "created_at"、type = "datetime") <br/> * /
 - private $ createdAt ;
 - / ** <br/> *コンストラクター <br/> * /
 - パブリック関数 __construct()
 - {
 - $ this-> createdAt = new \ DateTime ();
 - }
 - / ** <br/> *文字列 <br/>へ* /
 - パブリック関数 __toString()
 - {
 - return $ this-> getUrl();
 - }
 - / ** <br/> * Get id <br/> * <br/> * @return integer $ id <br/> * /
 - パブリック関数 getId()
 - {
 - $ this-> id;
 - }
 - / ** <br/> * URLを設定 <br/> * <br/> * @param string $ url <br/> * /
 - パブリック関数 setUrl( $ url )
 - {
 - $ this-> url = $ url ;
 - }
 - / ** <br/> * URLを取得 <br/> * <br/> * @return string $ url <br/> * /
 - パブリック関数 getUrl()
 - {
 - return $ this-> url;
 - }
 - / ** <br/> *セットCreateAt <br/> * <br/> * @param datetime $ createdAt <br/> * /
 - パブリック関数 setCreatedAt( $ createdAt )
 - {
 - $ this-> createdAt = $ createdAt ;
 - }
 - / ** <br/> * Get CreateAt <br/> * <br/> * @return datetime $ createdAt <br/> * /
 - パブリック関数 getCreatedAt()
 - {
 - return $ this-> createdAt;
 - }
 - }
 
クラスプロパティにアクセスするためのメソッドを導入しました。
ルーティングルールをrouting.ymlに追加します
Copy Source | Copy HTML
- link_list :
 - パターン :/
 - デフォルト : { _bundle :ReadlaterBundle、 _controller :Readlater、 _action :index }
 - add_link :
 - パターン :/追加
 - デフォルト : { _bundle :ReadlaterBundle、 _controller :Readlater、 _action :add }
 - read_link :
 - パターン :/読み取り/:id
 - デフォルト : { _bundle :ReadlaterBundle、 _controller :Readlater、 _action :read }
 
コードから、すべてが明確であると思います。リスト、追加、削除の3つのルールがあります。
最後に、Doctrineを実行しているオブジェクトを操作する方法を確認できるコントローラーです。 コード全体をすぐに引用します。
Copy Source | Copy HTML
- <?php
 - 名前空間 Application \ ReadlaterBundle \ Controller;
 - Symfony \ Framework \ WebBundle \ Controllerを使用し、
 - アプリケーション\ ReadlaterBundle \エンティティ\リンク、
 - Doctrine \ ORM \ QueryBuilder;
 - ReadlaterController クラス は Controllerを拡張します
 - {
 - パブリック関数 indexAction()
 - {
 - $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
 - $ links = $ em-> getRepository( 'Application \\ ReadlaterBundle \ Entities \ Link' )-> findAll();
 - return $ this- > render( 'ReadlaterBundle:Readlater:index' 、 array ( 'links' => $ links ));
 - }
 - パブリック関数 addAction()
 - {
 - $ request = $ this-> getRequest();
 - $ url = $ request-> request-> get( 'link' );
 - $ link = new Link();
 - $ link-> setUrl( $ url );
 - $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
 - $ em- > persist( $ link );
 - $ em- > flush();
 - return $ this- > redirect( $ this- > generateUrl( 'link_list' ));
 - }
 - パブリック関数 readAction( $ id )
 - {
 - $ em = $ this-> container-> getDoctrine_ORM_EntityManagerService();
 - $ link = $ em- > find( 'Application \\ ReadlaterBundle \\ Entities \\ Link' 、 $ id );
 - $ em- > remove( $ link );
 - $ em- > flush();
 - return $ this- > redirect( $ this- > generateUrl( 'link_list' ));
 - }
 - }
 
コードに関するいくつかの言葉。
$em = $this->container->getDoctrine_ORM_EntityManagerService();
      
      したがって、DIコンテナを使用して、 EntityManagerにアクセスします
$em->getRepository()
      
      -これは特定のタイプのオブジェクト、つまり何らかのアナログのオブジェクトのストレージを取得する方法です* Doctrine 1.xのテーブル。
$em->persist($link);
      
      -オブジェクトを保存します
$em->flush()
      
      トランザクションを完了します。つまり、実際にデータベースにデータを送信します。
$em->remove($link)
      
      -
$em->remove($link)
      
      、オブジェクトを削除してください。
ところで、 Symfony \ Framework \ DoctrineBundle \ Controller \ DoctrineControllerからコントローラーを継承した場合、メソッドは利用可能になります:
- getDatabaseConnection-データベース接続オブジェクトを返します
 - getEntityManager -DI Container'aから取得する必要はありません
 - createQueryBuilder
 - createQuery
 
これがコードのすべてです。残りは明らかだと思います。
しかし、おそらくテーブルクラスがない場合、モデルオブジェクトを抽出するためのメソッドをどこで作成するかという疑問が生じました。 たとえば、この場合、 findAllメソッドが、降順で追加された日付でソートされたオブジェクトのリストを取得すると便利です。 これを行うには、特定のタイプのオブジェクト用に独自のストレージリポジトリクラスを作成します。
これを行うには、 Linkクラスを開き、ファイルの最後に追加します。
Copy Source | Copy HTML
- / ** <br/> * LinkRepository <br/> * /
 - クラス LinkRepository は EntityRepositoryを拡張します
 - {
 - パブリック関数 findAll()
 - {
 - return $ this- > _ em-> createQuery( 'SELECT l FROM Application \\ ReadlaterBundle \\ Entities \\ Link l ORDER BY l.createdAt DESC' )-> getResult();
 - }
 - }
 
これがリポジトリになります。
ここで、 Linkクラスに使用するリポジトリを考えてみましょう。このため、 LinkクラスのDocblockをわずかに変更します
Copy Source | Copy HTML
- / ** <br/> * @Entity(repositoryClass = "Application \ ReadlaterBundle \ Entities \ LinkRepository") <br/> * @Table(name = "readlater_link") <br/> * /
 - クラスリンク
 - {
 - // ...
 - }
 
それは基本的にそれです。 これで、リンクのリストは正しい順序でソートされ、次のようになります。
 
      テンプレートコードは引用しませんでしたが、これらはすべてgithubのソースコードで確認できます
関連リンクも: