Skip to content

Commit 9d44bf6

Browse files
committed
Promote DQL queries instead of QueryBuilder
1 parent fe0725d commit 9d44bf6

File tree

4 files changed

+79
-64
lines changed

4 files changed

+79
-64
lines changed

doctrine.rst

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -701,28 +701,30 @@ a new method for this to your repository::
701701
}
702702

703703
/**
704-
* @param $price
705704
* @return Product[]
706705
*/
707706
public function findAllGreaterThanPrice($price): array
708707
{
709-
// automatically knows to select Products
710-
// the "p" is an alias you'll use in the rest of the query
711-
$qb = $this->createQueryBuilder('p')
712-
->andWhere('p.price > :price')
713-
->setParameter('price', $price)
714-
->orderBy('p.price', 'ASC')
715-
->getQuery();
716-
717-
return $qb->execute();
718-
719-
// to get just one result:
720-
// $product = $qb->setMaxResults(1)->getOneOrNullResult();
708+
$entityManager = $this->getEntityManager();
709+
710+
$query = $entityManager->createQuery(
711+
'SELECT p
712+
FROM App\Entity\Product p
713+
WHERE p.price > :price
714+
ORDER BY p.price ASC'
715+
)->setParameter('price', $price);
716+
717+
// returns an array of Product objects
718+
return $query->getResult();
721719
}
722720
}
723721

724-
This uses Doctrine's `Query Builder`_: a very powerful and user-friendly way to
725-
write custom queries. Now, you can call this method on the repository::
722+
The string passed to ``createQuery()`` might look like SQL, but it is
723+
`Doctrine Query Language`_. This allows you to type queries using commonly
724+
known query language, but referencing PHP objects instead (i.e. in the ``FROM``
725+
statement).
726+
727+
Now, you can call this method on the repository::
726728

727729
// from inside a controller
728730
$minPrice = 1000;
@@ -736,36 +738,46 @@ write custom queries. Now, you can call this method on the repository::
736738
If you're in a :ref:`services-constructor-injection`, you can type-hint the
737739
``ProductRepository`` class and inject it like normal.
738740

739-
For more details, see the `Query Builder`_ Documentation from Doctrine.
741+
Querying with the Query Builder
742+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
740743

741-
Querying with DQL or SQL
742-
------------------------
743-
744-
In addition to the query builder, you can also query with `Doctrine Query Language`_::
744+
Doctrine also provides a `Query Builder`_, an object-oriented way to write
745+
queries. It is recommended to use this when queries and build dynamically (i.e.
746+
based on PHP conditions)::
745747

746748
// src/Repository/ProductRepository.php
747-
// ...
748749

749-
public function findAllGreaterThanPrice($price): array
750+
// ...
751+
public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array
750752
{
751-
$entityManager = $this->getEntityManager();
753+
// automatically knows to select Products
754+
// the "p" is an alias you'll use in the rest of the query
755+
$qb = $this->createQueryBuilder('p')
756+
->andWhere('p.price > :price')
757+
->setParameter('price', $price)
758+
->orderBy('p.price', 'ASC')
759+
760+
if (!$includeUnavailableProducts) {
761+
$qb->andWhere('p.available = :available')
762+
->setParameter('available', true);
763+
}
752764

753-
$query = $entityManager->createQuery(
754-
'SELECT p
755-
FROM App\Entity\Product p
756-
WHERE p.price > :price
757-
ORDER BY p.price ASC'
758-
)->setParameter('price', $price);
765+
$query = $qb->getQuery();
759766

760-
// returns an array of Product objects
761767
return $query->execute();
768+
769+
// to get just one result:
770+
// $product = $query->setMaxResults(1)->getOneOrNullResult();
762771
}
763772

764-
Or directly with SQL if you need to::
773+
Querying with SQL
774+
~~~~~~~~~~~~~~~~~
775+
776+
In addition, you can query directly with SQL if you need to::
765777

766778
// src/Repository/ProductRepository.php
767-
// ...
768779

780+
// ...
769781
public function findAllGreaterThanPrice($price): array
770782
{
771783
$conn = $this->getEntityManager()->getConnection();

doctrine/associations.rst

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -471,15 +471,17 @@ following method to the ``ProductRepository`` class::
471471
// src/Repository/ProductRepository.php
472472
public function findOneByIdJoinedToCategory($productId)
473473
{
474-
return $this->createQueryBuilder('p')
475-
// p.category refers to the "category" property on product
476-
->innerJoin('p.category', 'c')
477-
// selects all the category data to avoid the query
478-
->addSelect('c')
479-
->andWhere('p.id = :id')
480-
->setParameter('id', $productId)
481-
->getQuery()
482-
->getOneOrNullResult();
474+
$entityManager = $this->getEntityManager();
475+
476+
$query = $entityManager->createQuery(
477+
'SELECT p, c
478+
FROM App\Entity\Product p
479+
INNER JOIN p.category c
480+
WHERE p.id = :id
481+
'
482+
)->setParameter('id', $productId);
483+
484+
return $query->getOneOrNullResult();
483485
}
484486

485487
This will *still* return an array of ``Product`` objects. But now, when you call

messenger/custom-transport.rst

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ Here is a simplified example of a database transport::
5858
public function get(): iterable
5959
{
6060
// Get a message from "my_queue"
61-
$row = $this->db->createQueryBuilder()
62-
->from('my_queue')
63-
->where('delivered_at is null OR delivered_at < :redeliver_timeout')
64-
->andWhere('handled = :false')
61+
$row = $this->db->createQuery(
62+
'SELECT *
63+
FROM my_queue
64+
WHERE (delivered_at is null OR delivered_at < :redeliver_timeout')
65+
AND handled = :false
66+
)
6567
->setParameter('redeliver_timeout', new DateTimeImmutable('-5minutes'))
6668
->setParameter('false', false)
6769
->getOneOrNullResult();
@@ -85,13 +87,9 @@ Here is a simplified example of a database transport::
8587
}
8688

8789
// Mark the message as "handled"
88-
$this->db->createQueryBuilder()
89-
->update('my_queue')
90-
->setValues([
91-
'handled' => true
92-
])
93-
->where('id = :id')
90+
$this->db->createQuery('UPDATE my_queue SET handled = :true WHERE id = :id')
9491
->setParameter('id', $stamp->getId())
92+
->setParameter('true', true)
9593
->execute();
9694
}
9795

@@ -103,9 +101,7 @@ Here is a simplified example of a database transport::
103101
}
104102

105103
// Delete the message from the "my_queue" table
106-
$this->db->createQueryBuilder()
107-
->delete('my_queue')
108-
->where('id = :id')
104+
$this->db->createQuery('DELETE FROM my_queue WHERE id = :id')
109105
->setParameter('id', $stamp->getId())
110106
->execute();
111107
}
@@ -116,14 +112,15 @@ Here is a simplified example of a database transport::
116112
$uuid = Uuid::uuid4()->toString();
117113

118114
// Add a message to the "my_queue" table
119-
$this->db->createQueryBuilder()
120-
->insert('my_queue')
121-
->values([
122-
'id' => $uuid,
123-
'envelope' => $encodedMessage['body'],
124-
'delivered_at' => null,
125-
'handled' => false,
126-
]);
115+
$this->db->createQuery(
116+
'INSERT INTO my_queue (id, envelope, delivered_at, handled)
117+
VALUES (:id, :envelope, :delivered_at, :handled)'
118+
)
119+
->setParameter('id', $uuid)
120+
->setParameter('envelope', $encodedMessage['body'])
121+
->setParameter('delivered_at', null)
122+
->setParameter('handled', false)
123+
->execute();
127124

128125
return $envelope->with(new TransportMessageIdStamp($uuid));
129126
}

security/user_provider.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,12 @@ interface only requires one method: ``loadUserByUsername($username)``::
137137

138138
public function loadUserByUsername($usernameOrEmail)
139139
{
140-
return $this->createQueryBuilder('u')
141-
->where('u.username = :query OR u.email = :query')
140+
return $this->createQuery(
141+
'SELECT u
142+
FROM App\Entity\User u
143+
WHERE u.username = :query
144+
OR u.email = :query'
145+
)
142146
->setParameter('query', $usernameOrEmail)
143147
->getQuery()
144148
->getOneOrNullResult();

0 commit comments

Comments
 (0)