如何在教义 2 实体的存储库中使用复杂的标准?

2022-08-30 11:45:27

假设我有一个表格,其中包含有关节日的信息。
每个节日都有开始和结束的日期。

我想选择在给定日期直播(发生)的所有节日。

这意味着,我想选择所有节日,它们的开始日期在给定日期之前或之前,并且它们的结束日期是在同一给定日期之后或在同一日期。

因此,我继续使用节日实体的存储库类,并创建了一个方法来做到这一点。
但是 criteria 参数 “findBy” 期望是一个数组,所有示例仅将其视为简单条件(例如,“array('name' => 'billy')”将选择其名称列中具有值 billy 的所有行),它仅使用比较运算符。

如何使用其他运算符,例如

>, <, !=, IN, NOT IN, LIKE    

等等?


答案 1

Doctrine 2.3 添加了一个 match() 方法,允许您使用条件

Jeremy Hicks的例子可以这样写(注意,这返回的是ArrayCollection而不是数组)。

public function findActiveFestivals($start, $end)
{
    $expr = Criteria::expr();
    $criteria = Criteria::create();
    $criteria->where($expr->gte('start', $start));
    $criteria->andWhere($expr->lte('end', $end);
    return $this->matching($criteria);
}

就个人而言,我不会在这里使用和where,而是使用更多的行来提高可读性,如下所示:

public function findActiveFestivals($start, $end)
{
    $expr = Criteria::expr();
    $criteria = Criteria::create();
    $criteria->where(
      $expr->andX(
        $expr->gte('start', $start),
        $expr->lte('end', $end)
      )
    );
    return $this->matching($criteria);
}

使用 IN 子句非常简单。

public function findFestivalsByIds($ids)
{
    $expr = Criteria::expr();
    $criteria = Criteria::create();
    $criteria->where($expr->in('id', $ids));
    return $this->matching($criteria);
}

Criteria 类位于 Doctrine 的 not-real-ORM-or-DBAL Common 的命名空间中,就像它们的 ArrayCollection(它支持 Criteria 的时间比 EntityRepository 长)。

它旨在成为非存储库代码创建拟合标准的一种解耦方式。因此,在存储库外部使用此类应该没问题。QueryBuilder最近也支持Criteriment。因此,即使在构建需要QueryBuilder的更复杂的查询时,您也可以使用条件为非数据库代码提供请求的灵活性。


答案 2

如果你想要一些特定的东西,你需要编写自己的查询(可能使用DQL)。我相信内置的“findBy”方法更适合于快速抓取对象,如果你的标准不那么具体的话。我不知道您的实体名称或它们的存储位置。可能是像这样的功能,作为您的节日存储库中的一个功能。

public function findActiveFestivals($start, $end)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('f')
        ->from('Festival', 'f')
        ->where('f.start >= :start')
        ->andWhere('f.end <= :end')
        ->setParameters(array('start' => $start, 'end' => $end));

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

推荐