存储库的最佳实践是什么?

时间:2016-09-23 13:09:26

标签: doctrine-orm doctrine symfony

在我的存储库中,我有太多参数的方法(用于哪里):

示例:

class ProchaineOperationRepository extends EntityRepository
{
        public function getProchaineOperation(
            $id = null, // Search by ID
            \DateTime $dateMax = null, // Search by DateMax
            \DateTime $dateMin = null, // Search by DateMin
            $title = null // Search by title
        )

在我的控制器中,我有不同的操作...获取 ID ,获取 ID和DateMin 获取 ID和标题,...

我的方法太难以辨认了,因为参数太多了......创建很多方法很难,因为它们几乎相同...

最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

您的问题中有两个主要问题

  
      
  1. 您的存储库方法中有太多参数将用于'其中'最终查询的条件。你想以更好的方式组织它们
  2.   
  3. 由于传递的参数可能很复杂,
  4. 应该以有意义的方式从控制器调用存储库方法   

我建议您编写一个Repository方法,如:

namespace AcmeBundle\Repository;

/**
 * ProchaineOperationRepository
 *
 */
class ProchaineOperationRepository extends \Doctrine\ORM\EntityRepository
{
    public function search($filters, $sortBy = "id", $orderBy = "DESC")
    {
        $qb = $this->createQueryBuilder("po");

        foreach ($filters as $key => $value){
            $qb->andWhere("po.$key='$value'");
        }

        $qb->addOrderBy("po.$sortBy", $orderBy);

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

这里的$filters变量是一个数组,它应该包含您将要使用的过滤器'其中'条件。 $sortBy$orderBy对于以正确排序的方式获得结果也很有用

现在,您可以从控制器调用存储库方法,如:

class ProchaineOperationController extends Controller
{
    /**
     * @Route("/getById/{id}")
     */
    public function getByIdAction($id)
    {
        $filters = ['id' => $id];

        $result = $this->getDoctrine()->getRepository("AcmeBundle:ProchaineOperation")->search($filters);
        //process $result
    }

    /**
     * @Route("/getByTitle/{title}")
     */
    public function getByTitleAction($title)
    {
        $filters = ['title' => $title];
        $sortBy = 'title';

        $result = $this->getDoctrine()->getRepository("AcmeBundle:ProchaineOperation")->search($filters, $sortBy);
        //process $result

    }

    /**
     * @Route("/getByIdAndDateMin/{id}/{dateMin}")
     */
    public function getByIdAndDateMinAction($id, $dateMin)
    {
        $filters = ['id' => $id, 'dateMin' => $dateMin];
        $sortBy = "dateMin";
        $orderBy = "ASC";

        $result = $this->getDoctrine()->getRepository("AcmeBundle:ProchaineOperation")->search($filters, $sortBy, $orderBy);
        //process $result
    }

}

请注意,您正在为所有控制器操作调用相同的存储库方法,并根据您的参数进行微小更改。另请注意,$sortBy$orderBy可选择传递。

希望它有所帮助!

答案 1 :(得分:1)

如果您的目标只是在每个属性之间使用AND运算符进行查询,那么最好的方法是使用doctrine提出的方法:findBy() cf:this part of the doc < / p>

例如:

$results = $this
            ->getDoctrine()
            ->getRepository('AppBundle:ProchaineOperation')
             ->findBy(array('dateMax' => $myDate, 'title' => 'Hello world');

编辑:评论后

然后使用与Doctrine相同的方式:只传递一个带有id,dateMax ...的数组作为键,如果这些是设置的话。这应该解决方法签名问题,这会给你带来很多麻烦。 :)