Przeglądaj źródła

ORM: querying with DQL or SQL.

Frederic G. MARAND 6 lat temu
rodzic
commit
8d0e9d04a9

+ 21 - 15
.idea/dataSources/d3f78662-f02a-4c3c-8ef4-7e8000862529.xml

@@ -906,46 +906,52 @@
       <Charset>utf8mb4</Charset>
       <DefaultForCharset>0</DefaultForCharset>
     </collation>
-    <table id="228" parent="4" name="groups">
+    <table id="228" parent="4" name="migration_versions">
       <Engine>InnoDB</Engine>
       <Collation>utf8_unicode_ci</Collation>
     </table>
-    <table id="229" parent="4" name="migration_versions">
+    <table id="229" parent="4" name="product">
       <Engine>InnoDB</Engine>
       <Collation>utf8_unicode_ci</Collation>
     </table>
-    <column id="230" parent="228" name="id">
+    <column id="230" parent="228" name="version">
+      <Position>1</Position>
+      <DataType>varchar(255)|0</DataType>
+      <NotNull>1</NotNull>
+      <ColumnKind>normal</ColumnKind>
+    </column>
+    <key id="231" parent="228" name="PRIMARY">
+      <NameSurrogate>1</NameSurrogate>
+      <ColNames>version</ColNames>
+      <Primary>1</Primary>
+    </key>
+    <column id="232" parent="229" name="id">
       <Position>1</Position>
       <DataType>int(11)|0</DataType>
       <NotNull>1</NotNull>
       <SequenceIdentity>1</SequenceIdentity>
       <ColumnKind>normal</ColumnKind>
     </column>
-    <column id="231" parent="228" name="name">
+    <column id="233" parent="229" name="name">
       <Position>2</Position>
       <DataType>varchar(100)|0</DataType>
       <NotNull>1</NotNull>
       <ColumnKind>normal</ColumnKind>
     </column>
-    <column id="232" parent="228" name="price">
+    <column id="234" parent="229" name="price">
       <Position>3</Position>
       <DataType>decimal(10,2)|0</DataType>
       <ColumnKind>normal</ColumnKind>
     </column>
-    <key id="233" parent="228" name="PRIMARY">
-      <NameSurrogate>1</NameSurrogate>
-      <ColNames>id</ColNames>
-      <Primary>1</Primary>
-    </key>
-    <column id="234" parent="229" name="version">
-      <Position>1</Position>
-      <DataType>varchar(255)|0</DataType>
+    <column id="235" parent="229" name="description">
+      <Position>4</Position>
+      <DataType>longtext|0</DataType>
       <NotNull>1</NotNull>
       <ColumnKind>normal</ColumnKind>
     </column>
-    <key id="235" parent="229" name="PRIMARY">
+    <key id="236" parent="229" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
-      <ColNames>version</ColNames>
+      <ColNames>id</ColNames>
       <Primary>1</Primary>
     </key>
   </database-model>

+ 12 - 2
src/Controller/ProductController.php

@@ -25,8 +25,18 @@ class ProductController extends Controller
    */
   public function index(ProductRepository $repository) {
     // Can also be fetched from the EntityManager, but simpler to inject it.
-    $products = $repository->findProductsLessThan(21);
-    return $this->render('product/index.html.twig', ['products' => $products]);
+    $priceLimit = 21;
+    $productsQB = $repository->findProductsLessThanQB($priceLimit);
+    $productsDQL = $repository->findProductsLessThanDQL($priceLimit);
+    $productsSQL = $repository->findProductsLessThanSQL($priceLimit);
+
+    // These two build the exact same query object.
+    assert($productsDQL === $productsQB);
+
+    // But these only return the same results, not the same query object.
+    assert($productsDQL == $productsSQL);
+
+    return $this->render('product/index.html.twig', ['products' => $productsQB]);
   }
 
   /**

+ 49 - 16
src/Repository/ProductRepository.php

@@ -8,20 +8,53 @@ use Symfony\Bridge\Doctrine\RegistryInterface;
 
 class ProductRepository extends ServiceEntityRepository
 {
-    public function __construct(RegistryInterface $registry)
-    {
-        parent::__construct($registry, Product::class);
-    }
-
-    public function findProductsLessThan($price)
-    {
-        $qb = $this->createQueryBuilder('p')
-          ->andWhere('p.price < :price')
-          ->setParameter('price', $price)
-          ->orderBy('p.price', 'ASC')
-          // ->setMaxResults(10)
-          ->getQuery();
-
-        return $qb->getResult();
-    }
+  public function __construct(RegistryInterface $registry)
+  {
+    parent::__construct($registry, Product::class);
+  }
+
+  public function findProductsLessThanQB(float $price)
+  {
+    $query = $this->createQueryBuilder('p')
+      ->andWhere('p.price < :price')
+      ->setParameter('price', $price)
+      ->orderBy('p.price', 'ASC')
+      // ->setMaxResults(10)
+      ->getQuery();
+
+    return $query->getResult();
+    // to get just one result:
+    // $product = $qb->setMaxResults(1)->getOneOrNullResult();
+  }
+
+  public function findProductsLessThanDQL(float $price)
+  {
+    $em = $this->getEntityManager();
+    $query = $em->createQuery(
+/** @lang DQL */'
+SELECT p
+FROM App\Entity\Product p
+WHERE p.price < :price
+ORDER BY p.price ASC
+    ')->setParameter('price', $price);
+
+    // returns an array of Product objects
+    return $query->execute();
+  }
+
+  public function findProductsLessThanSQL(float $price) {
+    $conn = $this->getEntityManager()->getConnection();
+
+    $sql = <<<SQL
+SELECT *
+FROM product p
+WHERE p.price < :price
+ORDER BY p.price ASC;
+SQL;
+    $stmt = $conn->prepare($sql);
+    $stmt->execute(['price' => $price]);
+
+    // returns an array of arrays (i.e. a raw data set).
+    return $stmt->fetchAll(\PDO::FETCH_CLASS, Product::class);
+  }
 }