1

假设我有一个实体User和一个实体Book,并且它们都被加入User.bookId = Book.id(这标志着用户拥有某本书,关系类型为 oneUserToManyBook)。

如果我现在想使用 Doctrine 的 DQL 或 QueryBuilder 执行性能友好的获取,那么在 Symfony2/Doctrine2 webapp 中实现这Books一点User的最佳方法是什么,以便我可以User在 Twig 模板的循环中使用它们?

枝条

{% for user in users %}
   {{ user.name|e }}
       {% for address in user.getAddressesByUserId(user.getId()) %}
           {{ address.city }}
       {% endfor %}
{% endfor %}

我看到了两种方法,但都没有达到我的目标:

第一种方法

创建一个自定义存储库类BookRepository

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT b.title
                             FROM MyBundle\Entity\User u,
                                  MyBundle\Entity\Book b
                             WHERE u.book_id = b.id'
                             AND u.id = :user_id)
              ->setParameter('user_id', $user_id)
              ->getResult();
}

问题:工作正常,但我无法调用getBooksOwnedByUser()我的 Twig 模板(因为它不绑定到实体User,而是绑定到它的存储库,它是Doctrine\ORM\EntityRepository.


第二种方法

执行与上面相同的查询 - 不是在我的UserRepository,而是直接在我的User实体类中。

这里的问题:我可以在我的 Twig 模板中调用这个方法,但我不能(也不应该)EntityManager在我的User实体类中使用。

4

1 回答 1

2

最好是建立从用户到图书的关系。假设您已经建立了这种关系,您可以像这样进行查询:

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT u, b
                            FROM MyBundle\Entity\User u
                            JOIN u.books b
                            WHERE  u.id = :user_id')
                        ->setParameter('user_id', $user_id)
                        ->getResult();
}

然后在你的控制器中:

$em = $this->getDoctrine()->getManager();
$user_with_books = $em->getRepository('MyBundle\Entity\User')
    ->getBooksOwnedByUser($user->getId());

return $this->render('YourTemplate.html.twig', array(
        'user_with_books' => $user_with_books,
));

在树枝中:

{% for book in user.books %}
    {{ book.title }}
{% endfor %}

一些考虑:

  1. 对于多个用户,您将不得不更改查询(延迟加载是可能的,但不建议)。
  2. 如果数据很多,您可以通过获取标量结果(数组)来提高性能
  3. 如果您需要对无法组合的用户进行不同的查询,则必须存储不同的变量(对象或数组)。这就是为什么我将它命名为“user_with_books”。但是,如果您的模板中只有该用户,您也可以将其称为“用户”。
  4. user.getAddressesByUserId(user.getId())<-- 将数据从一个模型传递到查询是控制器(或服务)的职责。最佳做法是避免在您的模板中执行此操作。

所以答案是:你不能用自定义存储库方法做任何事情,因为它是一个函数。函数本身不代表任何数据。所以这是一种您可以使用该函数检索实际数据并显示它的方法。

于 2013-08-16T17:13:40.693 回答