Dor*_*ron 34 php sql doctrine criteria doctrine-orm
让我们说我有一张桌子,里面有关于节日的信息.
每个节日都有开始和结束日期.
我想选择在给定日期生活(发生)的所有节日.
这意味着,我想选择他们的开始日期在给定日期之前或之后的所有节日,以及他们的结束日期是在同一日期之后或之后.
所以我继续了节日实体的存储库类,并创建了一个方法来做到这一点.
但是标准参数"findBy"期望的是一个数组,所有的例子都只将其视为一个简单的标准(例如"array('name'=>'billy')"将选择所有具有billy值的行. name column),它只使用比较运算符.
我怎样才能使用其他运算符
>, <, !=, IN, NOT IN, LIKE
Run Code Online (Sandbox Code Playgroud)
等等. ?
谢谢
Ree*_*e45 89
Doctrine 2.3添加了一个匹配()方法,允许您使用Criteria.
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);
}
Run Code Online (Sandbox Code Playgroud)
就个人而言,我不会在这里使用和使用更多的行来提高可读性,如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
使用IN子句非常简单.
public function findFestivalsByIds($ids)
{
$expr = Criteria::expr();
$criteria = Criteria::create();
$criteria->where($expr->in('id', $ids));
return $this->matching($criteria);
}
Run Code Online (Sandbox Code Playgroud)
Criteria类在Doctrine的非真正ORM或DBAL Common的命名空间中,就像它们的ArrayCollection(它支持的Criteria比EntityRepository更长).
它的意思是非存储库代码创建sophicated标准的解耦方式.所以在存储库之外使用这个类应该没问题.QueryBuilder 最近也支持Criteria.因此,即使在构建需要QueryBuilder的更复杂的查询时,您也可以使用Criteria为其提供非数据库代码的灵活性.
Jer*_*cks 22
如果你想要特定的东西,你需要编写自己的查询(可能使用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();
}
Run Code Online (Sandbox Code Playgroud)
小智 10
那不是Doron问题学说的答案有实体存储库,根本不能让我们使用查询...
$this->em->getRepository($this->entity)->findBy(array $criteria);
Run Code Online (Sandbox Code Playgroud)
但他怎么问是阵列的常规格式如何复杂的操作在数组$标准$criteria是array('field'=> $value);
小智 9
我曾经遇到过同样的问题,由于复杂的查询,我的Doctrine存储库变得非常难看.我还必须将Yii ActiveRecord(带有Criteria对象)转换为Doctrine,而Doctrine当时没有Criteria对象.
我找到了Benjamin Eberlei的博客文章,根据规范模式,这个问题有一个有趣的解决方案.
它使您能够将Query Builder对象的操作推迟到其他类.
$spec = new AndX(
new Equals('ended', 0),
new OrX(
new LowerThan('endDate', new \DateTime()),
new AndX(
new IsNull('endDate'),
new LowerThan('startDate', new \DateTime('-4weeks'))
)
)
);
return $this->em->getRepository('Advertisement')->match($spec)->execute()
Run Code Online (Sandbox Code Playgroud)
此外,您可以将2个或更多类组合在一起,从而创建可靠的可重用构建块:
public function myQuery(User $user)
{
$spec = new AndX(
new ExpiredAds(),
new AdsByUser($user)
);
return $this->em->getRepository('Advertisement')->match($spec)->execute();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,ExpiredAds()和AdsByUser()包含类似于第一个代码示例中的结构.
如果您认为该解决方案适合您,请让我建议您可以通过composer安装两个库:
| 归档时间: |
|
| 查看次数: |
69020 次 |
| 最近记录: |