我正在使用Doctrine'Common'Collections'Criteria::expr()
(NOT查询生成器表达式)。
isNotNull()
和notLike()
运算符似乎没有在这个类中实现。
在这种情况下,执行isNotNull()
和notLike()
的最佳方法是什么?
条件不为空
在doctrine/orm ^2.4
或doctrine/collections ^1.2
中,要具有与Criteria::expr()->isNotNull('field')
类似的is not null
,可以使用
$criteria = Criteria::create();
$expr = $criteria::expr();
$collection->matching($criteria->where($expr->neq('field', null)));
这与表达式生成器创建Expr::isNull
的方式相同,但通过:将比较运算符更改为Comparison::NEQ
return new Comparison($field, Comparison::EQ, new Value(null));
然后由QueryExpressionVisitor
和BasicEntityPersister
进行检查,用于将查询构建为Expr:isNotNull
。
case Comparison::NEQ:
if ($this->walkValue($comparison->getValue()) === null) {
return $this->expr->isNotNull($this->rootAlias . '.' . $comparison->getField());
}
标准LIKE和NOT LIKE
对于Criteria::expr()->like()
功能,Criteria::expr()->contains('property', 'value')
等效于SQL property LIKE %value%
。但是,它不允许更改为value%
或%value
,而是使用已与master合并的建议的startsWith
和endsWith
方法的拉取请求(自2.5.4起),因此可以与2.5.5一起发布。
不幸的是,对于Criteria::expr()->notLike()
和其他LIKE
变体,Criteria使用的'Doctrine'Common'Collections'ExpressionBuilder
不支持它们。
此外,如果未定义比较运算符(如Comparison::CONTAINS
),则QueryExpressionVisitor
和BasicEntityPersister
会引发错误,从而阻止手动定义自己的Comparison
功能。
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-集合
自定义存储库备选方案
最好的替代方案是使用自定义存储库和DBAL查询生成器表达式来替换所需的功能。
使用自定义实体存储库来过滤结果集将防止对集合进行完整的表读取,并提高使用缓存时的速度。
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#custom-存储库
集合筛选器备选方案
另一种选择是使用filter
来检索集合中的特定对象子集。
https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html#the-expr级
class MyEntity
{
public function getCollectionFieldNotLike($value)
{
return $this->getCollection()->filter(function($a) use ($value) {
return (false === stripos($a->getField(), $value));
});
}
public function getCollectionFieldLike($value)
{
return $this->getCollection()->filter(function($a) use ($value) {
return (false !== stripos($a->getField(), $value));
});
}
}
$entity->getCollectionFieldNotLike('value');
$entity->getCollectionFieldLike('value');
用于存储库中两者的过程语法组合。
$criteria = Criteria::create();
$expr = $criteria::expr();
$criteria->where($expr->neq('field', null));
$collection = $entityManager->getRepository('app:MyEntity')->matching($criteria);
$collectionNotLike = $collection->filter(function($a) {
return (false === strpos($a->getField(), 'value'));
});
请记住,如上所述,这将强制对集合读取完整的表,因为它需要检索记录才能过滤结果。