如何通过JOIN与Doctrine填充添加字段

时间:2017-03-02 09:36:47

标签: php mysql join doctrine-orm field

假设我有一个具有ManyToOne关系的实体(使用EXTRA_LAZY),显然是一个连接列。

eg. Article (main entity) -> Author (external entity)

假设我将一个字段author_name添加到未映射到ORM的文章中,并且在某些上下文中该字段应包含article->author->name值(通常它可以保持为空)。

当我查询文章列表时,我想自动填充article-author_name而不实现对查询结果的每个元素执行select的getter。我希望Doctrine在原始查询中使用简单的JOIN来获取和补充该值...

我不想将获取模式设置为EAGER以获得性能,就像在我的项目中一样,作者是一个非常复杂的实体。

这可能吗?

由于

1 个答案:

答案 0 :(得分:0)

可能我找到了解决方案。不知道这是否是最佳方式,但它有效。

我已经在主类中添加了一个字段getter

public getAuthorName() {
  return $this->author->name
}

在我的上下文中,这个getter只会在某些条件下被序列化程序调用。

在我的存储库代码中,我有一个特殊的方法(我重构,以便任何方法可以隐式调用它)在查询时强加Article-> author字段的填充。该方法只是使用querybuilder将LEFT JOIN添加到Author类,并在Article-> author上暂时将FetchMode设置为EAGER。

最后,可以使用简单的存储库方法

public findAllWithCustomHydration() {
    $qb = $this->createQueryBuilder('obj');
    $qb->leftJoin("obj.author", "a")
       -> addSelect("a"); //add a left join and a select so the query automatically retrive all needed values to populate Article and Author entities
    //you can chain left join for nested entities like the following
    //->leftJoin("a.address", "a_address")
    //-> addSelect("a_address");


    $q = $qb->getQuery()
              ->setFetchMode(Article::class, "author", ClassMetadata::FETCH_EAGER);
   //setFetchMode + EAGER tells Doctrine to prepopulate the entites NOW and not when the getter of  $article->author is called. 
   //I don't think that line is strictly required because Doctrine could populate it at later time from the same query result or maybe doctrine automatically set the field as EAGER fetch when a LEFT JOIN is included in the query, but i've not yet tested my code without this line.

    return $q->getResult();
}

con是你必须自定义每个查询或者更好地为repo的每个方法使用DQL / SQL / QueryBuilder但具有良好的重构,对于简单的包含情况,你可以编写一个注入该连接的泛型方法一个field_name数组。

希望得到这个帮助,如果找到更好的方法,请添加答案。

PS。我已经写了上面的代码,因为现在我不在我的笔记本上,希望它在第一次执行时有效。