代码样式:来自实体存储库的Doctrine2查询?

时间:2015-11-30 01:25:31

标签: symfony doctrine-orm coding-style entity knppaginator

据我所知,最好的代码风格是将复杂的SQL / DQL查询放到实体存储库中。

例如,有一个名为“新闻”的实体。它有一个名为“NewsRepository”的自己的实体存储库。

在控制器中有以下代码:

/**
 * @Route("/news", name="news")
 */
public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $paginator = $this->get('knp_paginator');

    $news = $paginator->paginate(
        $em->createQuery('SELECT n FROM AppBundle:News n'),
        $request->query->getInt('page', 1),
        10
    );

    return $this->render('app/news/list.html.twig', array(
        'news' => $news,
    ));
}

现在我想添加更多功能(过滤,按顺序排序,......)。那是因为我认为应该将查询移动到任何服务或实体存储库。但是最好的编码风格是怎样和最佳的?

(并且有没有人有很好的通用想法如何轻松添加过滤,按...排序?)

2 个答案:

答案 0 :(得分:1)

当然,

如果您想再次使用它,每个请求都应该在存储库中。不仅最复杂。

我会尝试回答您的第一个问题,然后给您一个可以帮助您进行“通用过滤”的提示

如果你想把你的请求放在repo中,只需在你的NewsRepository中创建:

public function findAllOrderedByDate() {
    $qb = $this->createQueryBuilder('n');
    $qb->orderBy('creationDate');

    return $qb->getQuery()->getResult();
}

在你的控制器中:

public function indexAction(Request $request)
{
    $newsRepo = $this->get('doctrine')->getRepository('AppBundle:News');
    $em = $this->getDoctrine()->getManager();
    $paginator = $this->get('knp_paginator');

    $news = $newsRepo->findAllOrderedByDate();
    $pagination = $paginator->paginate(
        $news,
        $request->query->getInt('page', 1),
        10
    );

    return $this->render('app/news/list.html.twig', array(
        'news' => $pagination,
    ));
}

对于过滤,你的报告中有一个技巧,即返回qb而不是直接结果。

同样,您可以创建一个函数,使用给定参数(使用addOrderBy()andWhere)添加orderBy并返回queryBuilder。毕竟,你可以处理。

编辑:

我在这个帖子上读到的解决方案:

public function findAllOrderedByDate(callable $func = null) {
    $qb = $this->createQueryBuilder('n');
    $qb->orderBy('creationDate');

    if (is_callable($func)) {
        return $func($qb);
    }
    return $qb->getQuery()->getResult();
}

并在您的控制器中:

$func = function (QueryBuilder $qb) use ($paginator, $request) {
    return $paginator->paginate($qb, $request->query->getInt('page', 1), 10);
};
$pagination = $em->getRepository('AppBundle:News')->findAllOrderedByDate($func);

答案 1 :(得分:0)

模型部件必须在模型部件中。将查询移至repo。 你的意思是什么,这样说:"很好的通用思想如何轻松添加过滤,按顺序排序"?
OrderBy
Where - 相同的链接