7

Doctrine 2 を使用して学業スケジュールをマッピングしています。関係を簡単に見てみると、次のようになります。

  • クラスにはイベントがあります(1 対多)
    • イベントにはタイプ(多対 1) があります
    • イベントには場所があります(多対 1)

I を使用すると、遅延ロードされたリレーションを使用して、クラス$em->find()のみを取得できます。または、結合で DQL を使用すると、オブジェクト グラフ全体を熱心に読み込むことができます。その中間にある解決策はありますか?

遅延ロードされたリレーションを含むクラスをフェッチし、特定の条件下で、イベントリレーションとすべてのイベントプロパティの熱心なロードをトリガーしたいと考えています。したがって、 のようなものを呼び出すと$class->getEventsHydrateAll()、すべてのイベントイベントの種類、およびイベントの場所が一度にハイドレートされます。

イベントスキーマを更新して、タイプ場所の関係にfetch="EAGER". しかし、この深い水分補給がいつ発生するかを制御したいと思います.

これは私のクラスリポジトリで行った 1 つの試みですが、Doctrine は各typelocationをルックアップするために個別のクエリを実行しています。

$query = $this->_em->createQuery('
        SELECT c FROM My\Entity\Class c
        WHERE c.id = :classId
');
$query->setParameter('classId', $classId)
      ->setFetchMode('My\Entity\Event', 'type', 'EAGER')
      ->setFetchMode('My\Entity\Event', 'location', 'EAGER');

try {
    return $query->getSingleResult();
} catch (\Doctrine\ORM\NoResultException $e) {
    return NULL;
}

Doctrineがこれをサポートしているかどうか誰か知っていますか? ありがとう!

4

2 に答える 2

5

TL;DR:

クラス プロパティで EAGER フラグを使用して、リレーションシップを熱心にロードすることができます。http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#manytoone

参考になるかどうかわかりませんが、私はこの方法で解決しました。

まず、私の状況の背景を少し説明します。現在、スコープを細かく制御したい OAuth 2 実装を作成しています。スコープは非常に細かく (電子メール、ユーザー名など) スターを付けることができ、読み取り、作成、編集、削除のそれぞれに個別のアクセス許可を設定できます。

以下は、その関係を大まかに示すデータベース ダイアグラムです。

ここに画像の説明を入力

したがって、私の問題は、たとえば、特定のトークンがユーザー名(スコープ)の読み取り(アクセス許可) を許可されているかどうかを確認するにはどうすればよいかということでした。

トークンをロードし、そのすべてのアクセス許可を取得してから、foreach読み取りアクセス許可を取得し、ユーザー名のスコープを確認すると、データベース アクセスが大量になります。

テストコード:

$permissions = $this->getOAuthHelper()
                    ->getAccessToken($accessToken)
                    ->getPermissions();
$results = [];
foreach ($permissions as $permission) {
    $results[] = $permission->getScope()->getTitle();
}
return $results;

クエリ ログ:

150630 10:49:47    54 Connect   root@localhost on api
150630 10:49:51    54 Query     SELECT t0.id AS id1, t0.token AS token2, t0.token_expiration AS token_expiration3, t0.refresh AS refresh4, t0.created_at AS created_at5, t0.deleted_at AS deleted_at6, t0.user_id AS user_id7, t0.client_id AS client_id8 FROM oauth_access_tokens t0 WHERE t0.token = 'user-test-token' LIMIT 1
                   54 Query     SELECT t0.id AS id1, t0.access_permission AS access_permission2, t0.scope_id AS scope_id3 FROM oauth_permissions t0 INNER JOIN oauth_access_to_permissions ON t0.id = oauth_access_to_permissions.permission_id WHERE oauth_access_to_permissions.access_id = '1'
150630 10:49:52    54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '1'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '2'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '3'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '4'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '5'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '6'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '7'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '8'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '9'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '10'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '11'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '12'
                   54 Query     SELECT t0.id AS id1, t0.title AS title2, t0.brief AS brief3, t0.category_id AS category_id4 FROM oauth_scopes t0 WHERE t0.id = '13'
                   54 Quit

ただし、ここでは、大部分がアクセス許可に関連付けられたスコープを収集していることがわかります。アクセス許可からスコープへの関係でeager フラグを使用して、アクセス許可を持つスコープを取得できます。

/**
 * @var Scope
 *
 * @ORM\ManyToOne(targetEntity="OAuthScope", fetch="EAGER")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="scope_id", referencedColumnName="id")
 * })
 */
protected $scope;

fetch="EAGER"ManyToOne アノテーションのフラグに注意してください。

まったく同じコードを実行すると、次のようになります。

150630 11:00:06    55 Connect   root@localhost on api
150630 11:00:10    55 Query     SELECT t0.id AS id1, t0.token AS token2, t0.token_expiration AS token_expiration3, t0.refresh AS refresh4, t0.created_at AS created_at5, t0.deleted_at AS deleted_at6, t0.user_id AS user_id7, t0.client_id AS client_id8 FROM oauth_access_tokens t0 WHERE t0.token = 'user-test-token' LIMIT 1
150630 11:00:11    55 Query     SELECT t0.id AS id1, t0.access_permission AS access_permission2, t0.scope_id AS scope_id3, t4.id AS id5, t4.title AS title6, t4.brief AS brief7, t4.category_id AS category_id8 FROM oauth_permissions t0 LEFT JOIN oauth_scopes t4 ON t0.scope_id = t4.id INNER JOIN oauth_access_to_permissions ON t0.id = oauth_access_to_permissions.permission_id WHERE oauth_access_to_permissions.access_id = '1'
                   55 Quit
于 2015-06-30T11:02:25.907 に答える