Doctrine Query Builder/DQL如何编写WHERE column = BINARY 'text'的查询
你的原始写法不生效,是因为DQL默认没有内置对MySQL BINARY 操作符的支持,直接将BINARY写在DQL语句中时,会被解析器判定为未知语法抛出错误。
以下是3种可行的实现方案:
方案1:使用DQL原生支持的CAST函数(推荐临时使用,无需额外配置)
Doctrine ORM 2.4及以上版本原生支持CAST函数,直接将字段转为二进制类型后比较即可达到和BINARY操作符完全一致的效果:
// 假设$repo是Records对应的仓库类 // 假设$name是待查询的名称,例如"My Record" $result = $repo->createQueryBuilder('r') ->select('r.id') ->where('CAST(r.name AS BINARY) = :name') ->setParameter('name', $name) ->getQuery() ->getResult();
方案2:自定义DQL函数(推荐频繁使用BINARY的场景)
如果项目中多处需要用到二进制比较,可以将BINARY注册为自定义DQL函数,后续可以直接在所有DQL语句中调用:
- 首先创建自定义函数类:
<?php // 可根据自己的项目结构调整存放路径,示例为src/Doctrine/Function/Binary.php namespace App\Doctrine\Function; use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; class Binary extends FunctionNode { public $stringPrimary; public function getSql(SqlWalker $sqlWalker) { return 'BINARY(' . $sqlWalker->walkStringPrimary($this->stringPrimary) . ')'; } public function parse(Parser $parser) { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $this->stringPrimary = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } }
- 在Doctrine配置中注册函数,以Symfony框架为例,修改
config/packages/doctrine.yaml:
doctrine: orm: dql: string_functions: BINARY: App\Doctrine\Function\Binary
- 注册完成后即可直接在QueryBuilder中使用:
$result = $repo->createQueryBuilder('r') ->select('r.id') ->where('BINARY(r.name) = :name') ->setParameter('name', $name) ->getQuery() ->getResult();
方案3:直接使用原生SQL查询
不需要适配DQL的场景下,也可以直接调用底层数据库连接执行原生SQL:
$conn = $repo->getEntityManager()->getConnection(); $result = $conn->executeQuery( 'SELECT id FROM Records WHERE name = BINARY ?', [$name] )->fetchAllAssociative();
内容的提问来源于stack exchange,提问作者cheryllium
相关产品推荐
相关产品推荐

