能否用Doctrine createNativeQuery返回跨实体的自定义字段集合?
在Symfony 6 + Doctrine 2.9中执行原生SQL并直接返回结果(无需实体映射)
完全可以在EntityManager结构内实现这个需求,下面提供两种实用方案:
方法一:直接使用数据库Connection对象(推荐)
通过EntityManager获取底层数据库连接,直接执行原生SQL并返回关联数组结果,全程不需要实体映射,和你在数据库CLI中执行的效果完全一致。
示例代码(控制器内):
// 获取EntityManager实例 $entityManager = $this->getDoctrine()->getManager(); // 获取数据库连接 $connection = $entityManager->getConnection(); // 编写你的原生SQL语句 $sql = " SELECT c.id AS car_id, c.color AS car_color, d.name AS dealer, d.location AS dealer_location, o.name AS owner_previous FROM car c JOIN dealership d ON c.dealership_id = d.id JOIN owner o ON c.previous_owner_id = o.id "; // 预处理并执行查询 $stmt = $connection->prepare($sql); $stmt->execute(); // 获取关联数组格式的结果集 $result = $stmt->fetchAllAssociative(); // 返回JSON响应 return $this->json($result);
方法二:用ResultSetMappingBuilder映射标量字段(兼容createNativeQuery)
如果一定要用createNativeQuery方法,可以通过ResultSetMappingBuilder仅映射标量字段,不需要关联任何实体类:
示例代码:
$entityManager = $this->getDoctrine()->getManager(); $sql = "SELECT c.id AS car_id, c.color AS car_color, d.name AS dealer, d.location AS dealer_location, o.name AS owner_previous FROM car c JOIN dealership d ON c.dealership_id = d.id JOIN owner o ON c.previous_owner_id = o.id"; // 初始化ResultSetMappingBuilder $rsm = new \Doctrine\ORM\Query\ResultSetMappingBuilder($entityManager); // 逐个添加需要返回的字段映射(字段别名 => 结果数组的键名) $rsm->addScalarResult('car_id', 'car_id'); $rsm->addScalarResult('car_color', 'car_color'); $rsm->addScalarResult('dealer', 'dealer'); $rsm->addScalarResult('dealer_location', 'dealer_location'); $rsm->addScalarResult('owner_previous', 'owner_previous'); // 创建并执行原生查询 $query = $entityManager->createNativeQuery($sql, $rsm); $result = $query->getResult(); // 返回JSON响应 return $this->json($result);
总结
- 方法一更简洁高效,适合不需要实体映射的场景,直接拿到和CLI执行一致的结果。
- 方法二适合必须使用
createNativeQuery的场景,通过标量映射避免实体依赖。
内容的提问来源于stack exchange,提问作者dbcn
相关产品推荐
相关产品推荐

