Skip to content

Commit 91dc8fa

Browse files
committed
Merge branch '4.4'
* 4.4: Use setParameters() when setting multiple parameters Promote DQL queries instead of QueryBuilder
2 parents f0764cc + d735f48 commit 91dc8fa

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
@@ -697,28 +697,30 @@ a new method for this to your repository::
697697
}
698698

699699
/**
700-
* @param $price
701700
* @return Product[]
702701
*/
703702
public function findAllGreaterThanPrice($price): array
704703
{
705-
// automatically knows to select Products
706-
// the "p" is an alias you'll use in the rest of the query
707-
$qb = $this->createQueryBuilder('p')
708-
->andWhere('p.price > :price')
709-
->setParameter('price', $price)
710-
->orderBy('p.price', 'ASC')
711-
->getQuery();
712-
713-
return $qb->execute();
714-
715-
// to get just one result:
716-
// $product = $qb->setMaxResults(1)->getOneOrNullResult();
704+
$entityManager = $this->getEntityManager();
705+
706+
$query = $entityManager->createQuery(
707+
'SELECT p
708+
FROM App\Entity\Product p
709+
WHERE p.price > :price
710+
ORDER BY p.price ASC'
711+
)->setParameter('price', $price);
712+
713+
// returns an array of Product objects
714+
return $query->getResult();
717715
}
718716
}
719717

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

723725
// from inside a controller
724726
$minPrice = 1000;
@@ -732,36 +734,45 @@ write custom queries. Now, you can call this method on the repository::
732734
If you're in a :ref:`services-constructor-injection`, you can type-hint the
733735
``ProductRepository`` class and inject it like normal.
734736

735-
For more details, see the `Query Builder`_ Documentation from Doctrine.
737+
Querying with the Query Builder
738+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
736739

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

742744
// src/Repository/ProductRepository.php
743-
// ...
744745

745-
public function findAllGreaterThanPrice($price): array
746+
// ...
747+
public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array
746748
{
747-
$entityManager = $this->getEntityManager();
749+
// automatically knows to select Products
750+
// the "p" is an alias you'll use in the rest of the query
751+
$qb = $this->createQueryBuilder('p')
752+
->where('p.price > :price')
753+
->setParameter('price', $price)
754+
->orderBy('p.price', 'ASC')
755+
756+
if (!$includeUnavailableProducts) {
757+
$qb->andWhere('p.available = TRUE')
758+
}
748759

749-
$query = $entityManager->createQuery(
750-
'SELECT p
751-
FROM App\Entity\Product p
752-
WHERE p.price > :price
753-
ORDER BY p.price ASC'
754-
)->setParameter('price', $price);
760+
$query = $qb->getQuery();
755761

756-
// returns an array of Product objects
757762
return $query->execute();
763+
764+
// to get just one result:
765+
// $product = $query->setMaxResults(1)->getOneOrNullResult();
758766
}
759767

760-
Or directly with SQL if you need to::
768+
Querying with SQL
769+
~~~~~~~~~~~~~~~~~
770+
771+
In addition, you can query directly with SQL if you need to::
761772

762773
// src/Repository/ProductRepository.php
763-
// ...
764774

775+
// ...
765776
public function findAllGreaterThanPrice($price): array
766777
{
767778
$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)