在Symfony2中,我在自定义存储库函数中获得了下一个代码:
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$any = "Jon";
$qb->select('s')
->from('AppBundle:Student', 's');
if ($criteria) {
foreach ($criteria as $field => $value) {
$qb->andWhere($qb->expr()->eq('s.' . $field, $value));
}
}
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('s.firstname', ":any"),
$qb->expr()->like('s.lastname', ":any"),
$qb->expr()->like('s.dni', ":any"),
$qb->expr()->like('s.email', ":any")
)
);
if ($offset) {
$qb->setFirstResult($offset);
}
if ($limit) {
$qb->setMaxResults($limit);
}
$query = $qb->getQuery();
$query->setParameter('any',(string) $any);
$logger->warning(__METHOD__ . ": " . json_encode($query->getSQL()));
$result = $query->getResult();
但$ result总是空的。也许是因为$ query-> getSQL()总是返回:
"SELECT p0_.id AS id0, p0_.firstname AS firstname1, p0_.lastname AS lastname2, p0_.email AS email3, p0_.dni AS dni4, p0_.phonenumber AS phonenumber5, p0_.active AS active6, p0_.birthdate AS birthdate7, p0_.sex AS sex8, p0_.discr AS discr9
FROM student s1_ INNER JOIN person p0_ ON s1_.id = p0_.id
WHERE p0_.active = 1 AND (p0_.firstname LIKE ? OR p0_.lastname LIKE ? OR p0_.dni LIKE ? OR p0_.email LIKE ?) LIMIT 15"
问题是,如果我拼错了参数名称,它会抛出异常,因此$ query-> setParameter行正在执行。它只是......不工作:S
更新1:
有人建议它可能是由重复使用的相同参数引起的。我将代码更新为:
(...)
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('s.firstname', ":fn"),
$qb->expr()->like('s.lastname', ":ln"),
$qb->expr()->like('s.dni', ":dni"),
$qb->expr()->like('s.email', ":email")
)
);
(...)
$query = $qb->getQuery();
$query->setParameters(array('fn' => $any, 'ln' => $any, "dni" => $any, "email" => $any));
没有变化。 :其中
更新2:
尝试
$qb->setParameters(array('fn' => $any, 'ln' => $any, "dni" => $any, "email" => $any));
$query = $qb->getQuery();
$logger->warning(__METHOD__ . ": " . json_encode($query->getSQL()));
......没有变化。
更新3:
按建议调试参数:
代码:
$query = $qb->getQuery();
$parameters = $qb->getQuery()->getParameters()->toArray();
foreach ($parameters as $parameter) {
$logger->warning(__METHOD__ . ": Parameter -> ".json_encode($parameter->getName())." = ".json_encode($parameter->getValue()));
}
$logger->warning(__METHOD__ . ": " . json_encode($query->getSQL()));
日志:
app.WARNING: AppBundle\Entity\StudentRepository::findByAny: Parameter -> "fn" = "Jon" [] []
app.WARNING: AppBundle\Entity\StudentRepository::findByAny: Parameter -> "ln" = "Jon" [] []
app.WARNING: AppBundle\Entity\StudentRepository::findByAny: Parameter -> "dni" = "Jon" [] []
app.WARNING: AppBundle\Entity\StudentRepository::findByAny: Parameter -> "email" = "Jon" [] []
app.WARNING: AppBundle\Entity\StudentRepository::findByAny: "SELECT p0_.id AS id0, p0_.firstname AS firstname1, p0_.lastname AS lastname2, p0_.email AS email3, p0_.dni AS dni4, p0_.phonenumber AS phonenumber5, p0_.active AS active6, p0_.birthdate AS birthdate7, p0_.sex AS sex8, p0_.discr AS discr9 FROM student s1_ INNER JOIN person p0_ ON s1_.id = p0_.id WHERE p0_.active = 1 AND (p0_.firstname = ? OR p0_.lastname = ? OR p0_.dni = ? OR p0_.email = ?) LIMIT 15" [] []
仍然没有结果,SQL仍显示“?”。虽然我认为我发现了错误......
答案 0 :(得分:0)
我建议您使用数字参数名称,然后拨打setParameters
而不是setParameter
。
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('s.firstname', "?0"),
$qb->expr()->like('s.lastname', "?1"),
$qb->expr()->like('s.dni', "?2"),
$qb->expr()->like('s.email', "?3")
)
);
$qb->setParameters([
'first name',
'last name',
'user dni',
'user.email@gmail.com'
]);
另一种选择可能是:
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('s.firstname', ":fn"),
$qb->expr()->like('s.lastname', ":ln"),
$qb->expr()->like('s.dni', ":dni"),
$qb->expr()->like('s.email', ":email")
)
)
$qb->setParameter('fn', 'first name');
$qb->setParameter('ln', 'last name');
$qb->setParameter('dni', 'user dni');
$qb->setParameter('email', 'user email');
编辑:刚刚检查过,添加了Artamiel提到的相同参数。
答案 1 :(得分:0)
...所以我想出来了(当然,在评论中提供了很多帮助)。这很简单,但它让我花了好几个小时。发生这种情况时,你不讨厌吗?
它不起作用,因为当你设置像
这样的参数时$qb->expr()->like('s.firstname', ":fn")
$qb->setParameters(array('fn' => $any));
您必须手动包含%字符:
$any = "%Jon%";
而不是
$any = "Jon";
当然,这是有道理的。您可能只想要其中一个边的%字符。
很有意义的是, $ query-> getSQL()仍然不会显示参数(仅限"?"字符)即使参数链接到QueryBuilder而不是Query本身,所以它就像:"重点是什么?"。
道德:不要相信Query-> getSQL()用于调试目的。几乎无用。
特别赞助用户@Artamiel