Skip to content

Commit d735f48

Browse files
committed
Merge branch '4.3' into 4.4
* 4.3: Use setParameters() when setting multiple parameters Promote DQL queries instead of QueryBuilder
2 parents 51b9c3f + 13b5db8 commit d735f48

File tree

4 files changed

+74
-63
lines changed

4 files changed

+74
-63
lines changed

doctrine.rst

Lines changed: 43 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,45 @@ 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+
->where('p.price > :price')
757+
->setParameter('price', $price)
758+
->orderBy('p.price', 'ASC')
759+
760+
if (!$includeUnavailableProducts) {
761+
$qb->andWhere('p.available = TRUE')
762+
}
752763

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);
764+
$query = $qb->getQuery();
759765

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

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

766777
// src/Repository/ProductRepository.php
767-
// ...
768778

779+
// ...
769780
public function findAllGreaterThanPrice($price): array
770781
{
771782
$conn = $this->getEntityManager()->getConnection();

doctrine/associations.rst

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -471,15 +471,16 @@ 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+
)->setParameter('id', $productId);
482+
483+
return $query->getOneOrNullResult();
483484
}
484485

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

messenger/custom-transport.rst

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ 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'))
66-
->setParameter('false', false)
6768
->getOneOrNullResult();
6869

6970
if (null === $row) {
@@ -85,12 +86,7 @@ Here is a simplified example of a database transport::
8586
}
8687

8788
// Mark the message as "handled"
88-
$this->db->createQueryBuilder()
89-
->update('my_queue')
90-
->setValues([
91-
'handled' => true
92-
])
93-
->where('id = :id')
89+
$this->db->createQuery('UPDATE my_queue SET handled = TRUE WHERE id = :id')
9490
->setParameter('id', $stamp->getId())
9591
->execute();
9692
}
@@ -103,9 +99,7 @@ Here is a simplified example of a database transport::
10399
}
104100

105101
// Delete the message from the "my_queue" table
106-
$this->db->createQueryBuilder()
107-
->delete('my_queue')
108-
->where('id = :id')
102+
$this->db->createQuery('DELETE FROM my_queue WHERE id = :id')
109103
->setParameter('id', $stamp->getId())
110104
->execute();
111105
}
@@ -116,14 +110,15 @@ Here is a simplified example of a database transport::
116110
$uuid = Uuid::uuid4()->toString();
117111

118112
// Add a message to the "my_queue" table
119-
$this->db->createQueryBuilder()
120-
->insert('my_queue')
121-
->values([
113+
$this->db->createQuery(
114+
'INSERT INTO my_queue (id, envelope, delivered_at, handled)
115+
VALUES (:id, :envelope, NULL, FALSE)'
116+
)
117+
->setParameters([
122118
'id' => $uuid,
123119
'envelope' => $encodedMessage['body'],
124-
'delivered_at' => null,
125-
'handled' => false,
126-
]);
120+
])
121+
->execute();
127122

128123
return $envelope->with(new TransportMessageIdStamp($uuid));
129124
}

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)