2012-09-14 126 views
6

我正在使用Doctrine 2來映射學術計劃。這裏有一個簡單看關係:學說:急於加載一個懶惰的關係的關係?

  • 一個事件(一到多)
    • 事件(多到一)
    • 一種事件具有位置(多到一個)

使用$em->find()我只能使用惰性加載關係獲取。或者在連接中使用DQL,我可以加載整個對象圖。中間是否有解決方案?

我想偷懶加載關係去取類,然後在一定條件下觸發事件關係的渴望負荷和所有事件性能。所以,當我打電話像$class->getEventsHydrateAll(),所有事件事件類型事件地點將被立即水合。

我想我可以通過更新我的事件架構標誌位置關係,因爲fetch="EAGER"做到這一點。但是我想要控制這種深度水合作用發生的時間。

這裏有一個嘗試我在資源庫做了,但原則是運行單個查詢查找每個位置

$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支持這個?謝謝!

+0

不知道它搞定,因爲你有3個級別,而不是2.嘗試 - >調用setFetchMode(「我的\實體\類」,「型」 ,'EAGER') –

回答

3

TL; DR:

您可以使用EAGER標誌上的類屬性有它加載它的關係熱切。 http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#manytoone

我不確定這是否會對您有幫助,但這是我解決問題的方法。

首先介紹一下我的情況。我目前正在創建一個OAuth 2實現,我希望在該範圍內對其進行細粒度控制。作用域非常精細(例如電子郵件地址,用戶名等),然後您可以爲它們分別設置各自的權限,以便讀取,創建,編輯和刪除。

下面是一個數據庫圖表鬆散表明關係:

enter image description here

所以我的問題是,如何我舉個例子,看看如果一個特定的標記允許閱讀(許可)一用戶名(範圍)?

如果我加載令牌,然後得到它的所有權限,那麼的foreach 閱讀允許,我檢查了用戶名範圍,那麼這是一個很大的數據庫訪問。

測試代碼:

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

查詢日誌:

150630 10:49:47 54 Connect [email protected] 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 

但是,我們可以在這裏看到的這大部分是收集連接到的權限範圍。我們可以用渴望標誌的關係從權限範圍與權限搶範圍:

/** 
* @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 [email protected] 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 
+0

備註:圖片來源於[PhpStorm](https://www.jetbrains.com/phpstorm/)。是的,我用root連接到我的數據庫,即使在開發中你也不應該這樣做。不,訪問令牌''user-test-token''不會幫助你破解我們的網站:p – DanielM