如何在Doctrine Query Builder select中用IF语句添加自定义列
Doctrine ORM 追加自定义计算列实现方案
你可以直接在原有查询逻辑基础上追加自定义字段,不需要改动原有全字段查询的逻辑,推荐使用DQL原生支持的语法实现,无需额外安装扩展。
推荐写法(跨数据库兼容,无额外依赖)
使用DQL原生支持的CASE WHEN表达式实现和MySQLIF()完全等价的判断逻辑,直接在select中追加字段,或使用addSelect在原有选择逻辑后追加即可:
// 写法1:直接在select中传入多个参数 ->createQueryBuilder() ->select('u', "CASE WHEN u.group = 1 THEN 'Yes' ELSE 'No' END AS isAdmin") ->from(User::class, 'u') // 写法2:不改动原有select代码,直接追加选择字段 ->createQueryBuilder() ->select('u') ->addSelect("CASE WHEN u.group = 1 THEN 'Yes' ELSE 'No' END AS isAdmin") ->from(User::class, 'u')
说明
- 第一个参数
u和原有逻辑一致,等价于原生SQL的u.*,会查询User实体映射的所有字段 - 第二个参数为自定义计算列,别名设为
isAdmin,逻辑和你给出的原生MySQLIF(u.group = 1, 'Yes', 'No')完全一致 - 该写法是DQL标准语法,兼容所有Doctrine支持的数据库,不需要修改任何配置
查询结果读取
查询返回的结果为混合格式,遍历结果时可以分别拿到实体对象和自定义计算列的值:
$res = $qb->getQuery()->getResult(); foreach ($res as $row) { /** @var User $user User实体实例,包含所有原有字段 */ $user = $row[0]; /** @var string $isAdmin 自定义计算列的值 */ $isAdmin = $row['isAdmin']; }
其他场景说明
如果你使用的是Doctrine DBAL(原生SQL查询构建器,不做ORM实体映射),可以直接使用MySQL原生IF()语法,不需要做转换:
$dbalConn->createQueryBuilder() ->select('u.*', "IF(u.group = 1, 'Yes', 'No') AS isAdmin") ->from('user', 'u')
如果是ORM场景一定要用IF()函数,需要先注册对应自定义DQL函数,从维护成本和兼容性考虑不推荐该方案。
内容的提问来源于stack exchange,提问作者user3174311
相关产品推荐
相关产品推荐

