当前位置: 首页 > 知识库问答 >
问题:

教义:渴望加载懒惰关系的关系?

邵耀
2023-03-14

我正在使用教义2来绘制学术时间表。以下是对这些关系的简化观察:

  • 一个类有事件(一对多)
    • 事件具有类型(多对一)
    • 一个事件有一个位置(多对一)

    使用$em-

    我想获取一个具有懒惰加载关系的类,然后在特定条件下触发事件关系和所有事件属性的急切加载。所以当我把类似$class这样的东西叫做

    我想我可以通过更新事件模式来实现这一点,将类型和位置关系标记为fetch=“EAGER”。但我想控制这种深层水合作用何时发生。

    这是我在类存储库中所做的一次尝试,但Doctrine正在运行单独的查询来查找每个类型和位置。

    $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;
    }
    

    有人知道教义是否支持这一点吗?谢谢!


共有2个答案

许博达
2023-03-14

我不确定,但我认为getSingleResult会覆盖水合模式。

尝试"执行",如本例所示:http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html#dql-temporarily-change-fetch-mode

罗法
2023-03-14

TL;博士:

您可以在类属性上使用EAGER标志来急切地加载它的关系。http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#manytoone

我不确定这是否对你有帮助,但我就是这样解决的。

首先介绍一下我的背景。我目前正在创建一个OAuth 2实现,我希望对范围进行精细的粒度控制。范围非常细粒度(例如电子邮件、用户名等),然后您可以对每个范围设置读取、创建、编辑和删除的单独权限。

下面是一个数据库图表,松散地显示了这种关系:

因此,我的问题是,例如,如何查看特定令牌是否允许读取(权限)用户名(范围)?

如果我加载令牌,然后获得它的所有权限,然后获得读取权限,我检查用户名范围,那么这是大量的数据库访问。

测试代码:

$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

但是,我们可以在这里看到,大部分内容是收集附加到权限的作用域。我们可以在从权限到范围的关系上使用“渴望”标志来获取具有以下权限的范围:

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

注意manytone注释上的fetch=“EAGER”标志。

现在,如果我们运行完全相同的代码:

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
 类似资料:
  • 我有一个问题,就是基于hasMany关系从数据库中获取数据并将其发送到Larave中的api。在下面的代码中,Laravel没有给我客户id=$id的产品。我不知道为什么,我不能在$query旁边发送$id。如果我把号码写在“我有很好的安全套,但我需要自动拿。 所有api代码 先谢谢你。

  • 问题内容: SQLAlchemy支持渴望加载关系,这基本上是一条语句。但是,如果模型具有两个或多个关系,则可能是非常庞大的联接。例如, 该查询的性能实在是太差了,因为中和会产生一个巨大的表。但是和在这里没有关系,因此它们不应该是。它应该是两个分开的查询。并且由于会话具有某种程度的缓存,因此我将查询更改为此。 这次的性能要好得多。但是,我不认为这样做是正确的。我不确定会话结束时标签缓存是否会过期。

  • 我已经阅读了本教程和这篇文章,但我不明白每种加载类型的确切用途。 我解释 我有这个POCO: 我明白这一点: > 对于懒惰加载:因为加载是懒惰的,如果我调用dbset将不会加载所有导航属性。这种类型的加载在性能和响应性方面是最好的。默认情况下启用它,如果我想重新启用它,我必须设置: 对于即时加载,它不是懒惰的:当我加载dpc\u-gestion时,它加载了所有导航属性。可以使用方法加载导航属性。要

  • 我有以下三个表格: 帖子 帖子: 评论: 标签: Post表有许多注释,comments表有许多与之关联的标记。 如何使用“快速加载”将所有这些表组合在一起? 比如: 但是这个查询总是在标记关系中返回空响应。 我做错了什么? 期望的结果是这样的: 你可以看到帖子里面包含评论,评论里面也包含标签关系。 另外,我在我的项目中使用了“jenssegers/laravel mongodb”包,我试图在没有

  • 拉威尔说: 我需要的是这样的东西 我们可以在一个关系中加载多个关系。 这有可能吗?

  • 问题内容: 如果按以下方式实现单例, 此实现与延迟初始化方法有何不同?在这种情况下,实例将在加载类时创建,并且仅在第一次使用时才加载类本身(例如,Singleton.getInstance(),而当您声明实例Singleton singleton = null;时则不会)。 即使采用惰性初始化方法,该实例也是在对getInstance()的调用上创建的 我在这里想念什么吗? 问题答案: 您也可以调