Symfony2数据库查询有三类主流方式:实体仓库方法适合单表固定查询,DQL适用于跨表关联和复杂条件,Query Builder用于动态条件和分页,原生SQL仅在必要时谨慎使用。

刚上手 Symfony2 的开发者,最常卡在数据库查询这一步。其实 Doctrine 提供了三类主流方式:实体仓库方法、DQL(Doctrine Query Language)和 Query Builder。它们各有适用场景,掌握基础用法就能覆盖 80% 的日常需求。
实体仓库的快捷查询
这是最简单直接的方式,适合条件明确、结构固定的单表操作。所有方法都基于 $repository = $em->getRepository('AppBundle:EntityName'):
-
$repository->find($id):按主键查单条,返回对象或null -
$repository->findOneBy(['name' => 'foo', 'status' => 1]):按字段值查一条,匹配第一条即停 -
$repository->findBy(['type' => 'book'], ['createdAt' => 'DESC']):查多条,支持排序,返回对象数组 -
$repository->findAll():全表查,慎用于大数据量表 - 支持动态方法名,如
findOneByNameAndPrice('Foo', 19.99)或findByStatusAndType(1, 'active')
DQL 原生风格查询
当需要跨表关联、聚合函数、复杂 WHERE 条件或必须控制 SQL 结构时,DQL 是首选。语法接近 SQL,但操作的是实体和属性而非表与字段:
- 基本写法:
$query = $em->createQuery('SELECT u FROM AppBundle:User u WHERE u.age > :age')->setParameter('age', 18)->getResult() - 查单条结果用
getSingleResult(),需配合 try-catch 防止无结果异常 - 只取标量值(如 COUNT、MIN)用
getSingleScalarResult() - 务必用
setParameter()绑定变量,避免拼接字符串导致 SQL 注入 - 支持
IN、BETWEEN、LIKE(如u.name LIKE :name+setParameter('name', '%foo%'))
Query Builder 构建动态查询
适合条件可变、需组合 where 子句或分页的场景,代码更易读、更安全:
- 从仓库创建:
$qb = $repository->createQueryBuilder('u') - 链式添加条件:
$qb->where('u.status = :status')->setParameter('status', 1) - 支持
andWhere()/orWhere()多条件叠加 - 分页必备:
->setFirstResult(0)->setMaxResults(10)相当于 LIMIT 0,10 - 最后调用
->getQuery()->getResult()执行
原生 SQL 查询(谨慎使用)
绕过 ORM,直连数据库执行 SQL。仅在性能关键、ORM 不支持或迁移脚本中使用:
- 获取连接对象:
$conn = $this->getDoctrine()->getConnection() -
$conn->fetchAssoc('SELECT * FROM user WHERE id = ?', [$id]):返回带键名的单行数组 -
$conn->fetchAll('SELECT name FROM user'):返回多行关联数组 -
$conn->fetchColumn('SELECT COUNT(*) FROM user'):返回第一列第一个值(如总数) - 参数同样推荐用占位符(
?或命名参数),不建议字符串拼接











