Skip to content

Query Builder

Build database queries with filters, joins, aggregates, subqueries, and reusable Criteria objects.

$qb = $entityManager->createQueryBuilder(User::class);
$users = $qb
->select('*')
->where('status', 'active')
->orderBy('created_at', 'DESC')
->limit(10)
->getResult();
  • where($field, $value) for equality.
  • whereIn($field, $values) for IN (...).
  • whereNull($field) and whereNotNull($field) for null checks.
  • whereExists($callback) for subqueries.
  • whereRaw($sql, ...$params) for escape-hatch SQL with bound parameters.

Use join, leftJoin, rightJoin, and crossJoin for table joins. Use count, sum, avg, max, and min for aggregate selects.

Implement CriteriaInterface when a filter should be reusable across repositories or commands, then apply it to a builder.

$orders = $this->entityManager
->createQueryBuilder(Order::class)
->whereNull('shipped_at')
->orderBy('placed_at', 'DESC')
->getResult();

Use whereRaw() only with bound parameters:

$qb->whereRaw('total > ?', [100]);

For large result sets, prefer bounded batches and clear the EntityManager between batches so the identity map does not grow without limit. See Performance for memory behavior.

chunk($size) wraps this in a generator that handles the limit/offset loop for you:

foreach ($qb->chunk(100) as $batch) {
foreach ($batch as $row) {
// process $row
}
$entityManager->clear();
}