2012-09-14 119 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