代码风格:来自实体存储库的 Doctrine2 查询?
Code Style: Doctrine2 queries from entity repository?
据我所知,最好的代码风格是将复杂的 SQL/DQL 查询放入实体存储库。
例如,有一个名为 "News" 的实体。它有一个名为 "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,
));
}
现在我想添加更多功能(过滤、排序...)。那是因为我认为应该将查询移动到任何服务或实体存储库。但是最好的编码风格是什么?
(有没有人有很好的通用想法,如何轻松添加过滤,排序依据...?)
模型部分必须在模型部分。将查询移动到回购协议。
你说这个是什么意思:"nice generic ideas how to easily add filtering, order by"?
OrderBy
Where - 相同 link
好的,
如果您想再次使用,每个请求都应该在存储库中。不仅最复杂。
我会尽量回答你的第一个问题,然后给你一个可以帮助你 "generic filtering"
的提示
如果你想将你的请求放入你的 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,
));
}
对于过滤,您的报告中有一个技巧,即 returning qb 而不是直接结果。
同样,您可以创建一个函数,使用给定参数(使用 addOrderBy()
或 andWhere
)添加您的 orderBy 以及 return 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);
据我所知,最好的代码风格是将复杂的 SQL/DQL 查询放入实体存储库。
例如,有一个名为 "News" 的实体。它有一个名为 "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,
));
}
现在我想添加更多功能(过滤、排序...)。那是因为我认为应该将查询移动到任何服务或实体存储库。但是最好的编码风格是什么?
(有没有人有很好的通用想法,如何轻松添加过滤,排序依据...?)
模型部分必须在模型部分。将查询移动到回购协议。
你说这个是什么意思:"nice generic ideas how to easily add filtering, order by"?
OrderBy
Where - 相同 link
好的,
如果您想再次使用,每个请求都应该在存储库中。不仅最复杂。
我会尽量回答你的第一个问题,然后给你一个可以帮助你 "generic filtering"
的提示如果你想将你的请求放入你的 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,
));
}
对于过滤,您的报告中有一个技巧,即 returning qb 而不是直接结果。
同样,您可以创建一个函数,使用给定参数(使用 addOrderBy()
或 andWhere
)添加您的 orderBy 以及 return 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);