如何构建动态学说查询?
How to build a dynamic doctrine query?
我正在尝试构建一个动态学说查询。当我这样尝试时,它起作用了
$qb->andWhere($qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq('t.width', '245'),
$qb->expr()->eq('t.height', '45'),
),
$qb->expr()->andX(
$qb->expr()->eq('t.width', '225'),
$qb->expr()->eq('t.height', '65'),
)
));
但我会从数组中传递键和值。
我的数组如下所示:
[
0 => [
"width" => "245"
"height" => "45"
]
1 => [
"width" => "225"
"height" => "65"
]
]
现在,我尝试了以下代码。
$conditions = $qb->expr()->orX(
$qb->expr()->andX()
);
foreach ($wheres as $outerKey => $outerValue) {
foreach ($outerValue as $innerKey => $innerValue) {
$conditions->add("te.$innerKey = :innerValue");
$qb->setParameter('innerValue', $innerValue);
}
}
$qb->andWhere($conditions);
dd($qb->getDQL());
但是返回的 SQL 与我尝试使用静态值时不一样。
所以你可以通过两种方式(我能想到的)来做到这一点。首先,使用上面显示的表达式,但带有额外的私有函数:
private function getExpressions(QueryBuilder $qb, array $fields)
{
$andX = $qb->expr()->andX();
foreach ($fields as $field => $value) {
$andX->add($qb->expr()->eq('t.' . $field, $value));
}
return $andX;
}
public function getDQL($conditions)
{
$qb = $this->createQueryBuilder('t');
$orX = $qb->expr()->orX();
foreach ($conditions as $i => $fields) {
$orX->add($this->getExpressions($qb, $fields));
}
$qb->add('where', $orX);
dump($qb->getDQL());
exit;
}
对我来说,弄清楚这个问题有点费时间。我实际上用上面提到的方式(手动构建 where 子句)做得更快:
$i = 0;
foreach ($conditions as $fields) {
$j = 0;
foreach ($fields as $field => $value){
$whereStr .= " " . $field . " = " . $value;
$j++;
if ($j < count($fields)){
$whereStr .= " AND";
}
}
$i++;
if ($i < count($conditions)){
$whereStr .= " OR";
}
}
如果我正确理解您的逻辑,这应该可行。如果我误解了您的要求,您可以切换 orX/andX 表达式。
我正在尝试构建一个动态学说查询。当我这样尝试时,它起作用了
$qb->andWhere($qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq('t.width', '245'),
$qb->expr()->eq('t.height', '45'),
),
$qb->expr()->andX(
$qb->expr()->eq('t.width', '225'),
$qb->expr()->eq('t.height', '65'),
)
));
但我会从数组中传递键和值。
我的数组如下所示:
[
0 => [
"width" => "245"
"height" => "45"
]
1 => [
"width" => "225"
"height" => "65"
]
]
现在,我尝试了以下代码。
$conditions = $qb->expr()->orX(
$qb->expr()->andX()
);
foreach ($wheres as $outerKey => $outerValue) {
foreach ($outerValue as $innerKey => $innerValue) {
$conditions->add("te.$innerKey = :innerValue");
$qb->setParameter('innerValue', $innerValue);
}
}
$qb->andWhere($conditions);
dd($qb->getDQL());
但是返回的 SQL 与我尝试使用静态值时不一样。
所以你可以通过两种方式(我能想到的)来做到这一点。首先,使用上面显示的表达式,但带有额外的私有函数:
private function getExpressions(QueryBuilder $qb, array $fields)
{
$andX = $qb->expr()->andX();
foreach ($fields as $field => $value) {
$andX->add($qb->expr()->eq('t.' . $field, $value));
}
return $andX;
}
public function getDQL($conditions)
{
$qb = $this->createQueryBuilder('t');
$orX = $qb->expr()->orX();
foreach ($conditions as $i => $fields) {
$orX->add($this->getExpressions($qb, $fields));
}
$qb->add('where', $orX);
dump($qb->getDQL());
exit;
}
对我来说,弄清楚这个问题有点费时间。我实际上用上面提到的方式(手动构建 where 子句)做得更快:
$i = 0;
foreach ($conditions as $fields) {
$j = 0;
foreach ($fields as $field => $value){
$whereStr .= " " . $field . " = " . $value;
$j++;
if ($j < count($fields)){
$whereStr .= " AND";
}
}
$i++;
if ($i < count($conditions)){
$whereStr .= " OR";
}
}
如果我正确理解您的逻辑,这应该可行。如果我误解了您的要求,您可以切换 orX/andX 表达式。