CRUD Operations ด้วย ORM: สร้าง อ่าน แก้ไข ลบ ข้อมูล
หลังจากที่เราได้เรียนรู้วิธีการสร้าง Entity Class เพื่อ Mapping Object กับ Table ในฐานข้อมูลแล้ว ในบทนี้เราจะมาดูวิธีการใช้งาน ORM เพื่อจัดการข้อมูลในฐานข้อมูล หรือที่เรียกว่า CRUD Operations ซึ่งย่อมาจาก Create (สร้าง), Read (อ่าน), Update (แก้ไข), และ Delete (ลบ) โดยเราจะใช้ Doctrine ORM เป็นตัวอย่างในการอธิบาย แต่หลักการเหล่านี้สามารถนำไปประยุกต์ใช้กับ ORM Framework อื่นๆ ได้เช่นกัน
ข้อดีของการใช้ ORM ในการทำ CRUD Operations คือ เราไม่จำเป็นต้องเขียน SQL Query โดยตรง ซึ่งช่วยลดความซับซ้อนของโค้ด ลดโอกาสในการเกิดข้อผิดพลาดจาก SQL Injection และทำให้โค้ดของเราอ่านง่ายและบำรุงรักษาได้ง่ายขึ้น
Creating Records (การสร้างข้อมูล)
การสร้างข้อมูลใหม่ในฐานข้อมูลผ่าน ORM ทำได้โดยการสร้าง Instance ของ Entity Class จากนั้นกำหนดค่าให้กับ Property ต่างๆ ของ Object และสั่งให้ ORM บันทึก Object นั้นลงในฐานข้อมูล
ตัวอย่างเช่น หากเรามี Entity Class ชื่อ Product ที่ Mapping กับตาราง products ในฐานข้อมูล เราสามารถสร้าง Product ใหม่ได้ดังนี้:
<?php
use App\Entity\Product;
// สร้าง Instance ของ Product Entity
$product = new Product();
$product->setName('เสื้อยืดคอกลม');
$product->setDescription('เสื้อยืดผ้า Cotton 100% ใส่สบาย');
$product->setPrice(299.00);
// ดึง Entity Manager จาก Doctrine
$entityManager = $this->getDoctrine()->getManager();
// บอก Entity Manager ว่าเราต้องการบันทึก Object นี้
$entityManager->persist($product);
// สั่งให้ Entity Manager บันทึกข้อมูลลงในฐานข้อมูล
$entityManager->flush();
echo 'บันทึก Product ใหม่เรียบร้อยแล้ว ID คือ: ' . $product->getId();
คำอธิบาย:
$product = new Product();สร้าง Instance ของ Entity ClassProduct$product->setName('เสื้อยืดคอกลม');กำหนดค่าให้กับ Propertynameของ Object$entityManager = $this->getDoctrine()->getManager();ดึง Instance ของEntityManagerซึ่งเป็น Object ที่ใช้จัดการ Entity ใน Doctrine$entityManager->persist($product);บอกEntityManagerว่าเราต้องการบันทึก Object$productลงในฐานข้อมูล (เป็นการเตรียมการก่อนบันทึกจริง)$entityManager->flush();สั่งให้EntityManagerบันทึกข้อมูลทั้งหมดที่เตรียมไว้ลงในฐานข้อมูล (เป็นการบันทึกจริง)
เหตุผลเชิงออกแบบ: การใช้ persist() และ flush() แยกกันทำให้เราสามารถบันทึก Object หลายตัวพร้อมกันได้ ซึ่งช่วยเพิ่มประสิทธิภาพในการทำงานเมื่อต้องบันทึกข้อมูลจำนวนมาก
Reading Records (การอ่านข้อมูล)
การอ่านข้อมูลจากฐานข้อมูลผ่าน ORM ทำได้โดยการใช้ Repository ของ Entity Class เพื่อ Query ข้อมูลตามเงื่อนไขต่างๆ
ตัวอย่างเช่น หากเราต้องการอ่าน Product ที่มี ID เท่ากับ 1 เราสามารถทำได้ดังนี้:
<?php
use App\Entity\Product;
// ดึง Repository ของ Product Entity
$productRepository = $this->getDoctrine()->getRepository(Product::class);
// ค้นหา Product ที่มี ID เท่ากับ 1
$product = $productRepository->find(1);
if ($product) {
echo 'ชื่อสินค้า: ' . $product->getName() . '<br>';
echo 'รายละเอียดสินค้า: ' . $product->getDescription() . '<br>';
echo 'ราคาสินค้า: ' . $product->getPrice() . '<br>';
} else {
echo 'ไม่พบสินค้า';
}
คำอธิบาย:
$productRepository = $this->getDoctrine()->getRepository(Product::class);ดึง Repository ของ Entity ClassProduct$product = $productRepository->find(1);ค้นหา Product ที่มี ID เท่ากับ 1 โดยใช้ Methodfind()ของ Repository
นอกจาก Method find() แล้ว Repository ยังมี Method อื่นๆ ให้ใช้งาน เช่น findAll() (อ่านข้อมูลทั้งหมด), findBy() (อ่านข้อมูลตามเงื่อนไข), และ findOneBy() (อ่านข้อมูลเพียง 1 Record ตามเงื่อนไข)
ตัวอย่าง: อ่าน Product ทั้งหมดที่มีราคามากกว่า 200 บาท
<?php
use App\Entity\Product;
$productRepository = $this->getDoctrine()->getRepository(Product::class);
$products = $productRepository->findBy(['price' => 200], ['name' => 'ASC']);
foreach ($products as $product) {
echo 'ชื่อสินค้า: ' . $product->getName() . '<br>';
echo 'ราคาสินค้า: ' . $product->getPrice() . '<br>';
}
คำอธิบาย:
$products = $productRepository->findBy(['price' => 200], ['name' => 'ASC']);ค้นหา Product ที่มีราคาเท่ากับ 200 บาท โดยเรียงลำดับตามชื่อจาก A-Z- อาร์กิวเมนต์แรก
['price' => 200]คือ Criteria (เงื่อนไข) ในการค้นหา - อาร์กิวเมนต์ที่สอง
['name' => 'ASC']คือ Order By (การเรียงลำดับ)
Updating Records (การแก้ไขข้อมูล)
การแก้ไขข้อมูลในฐานข้อมูลผ่าน ORM ทำได้โดยการดึง Object ที่ต้องการแก้ไขขึ้นมาก่อน จากนั้นแก้ไข Property ต่างๆ ของ Object และสั่งให้ ORM บันทึก Object นั้นลงในฐานข้อมูล
ตัวอย่างเช่น หากเราต้องการเปลี่ยนชื่อ Product ที่มี ID เท่ากับ 1 เป็น "เสื้อยืดคอกลมสีขาว" เราสามารถทำได้ดังนี้:
<?php
use App\Entity\Product;
$entityManager = $this->getDoctrine()->getManager();
$product = $entityManager->find(Product::class, 1);
if ($product) {
$product->setName('เสื้อยืดคอกลมสีขาว');
$entityManager->flush();
echo 'แก้ไข Product เรียบร้อยแล้ว';
} else {
echo 'ไม่พบสินค้า';
}
คำอธิบาย:
$product = $entityManager->find(Product::class, 1);ค้นหา Product ที่มี ID เท่ากับ 1 โดยใช้ Methodfind()ของEntityManager$product->setName('เสื้อยืดคอกลมสีขาว');กำหนดค่าใหม่ให้กับ Propertynameของ Object$entityManager->flush();สั่งให้EntityManagerบันทึกการเปลี่ยนแปลงลงในฐานข้อมูล
Deleting Records (การลบข้อมูล)
การลบข้อมูลออกจากฐานข้อมูลผ่าน ORM ทำได้โดยการดึง Object ที่ต้องการลบขึ้นมาก่อน จากนั้นสั่งให้ ORM ลบ Object นั้นออกจากฐานข้อมูล
ตัวอย่างเช่น หากเราต้องการลบ Product ที่มี ID เท่ากับ 1 เราสามารถทำได้ดังนี้:
<?php
use App\Entity\Product;
$entityManager = $this->getDoctrine()->getManager();
$product = $entityManager->find(Product::class, 1);
if ($product) {
$entityManager->remove($product);
$entityManager->flush();
echo 'ลบ Product เรียบร้อยแล้ว';
} else {
echo 'ไม่พบสินค้า';
}
คำอธิบาย:
$entityManager->remove($product);บอกEntityManagerว่าเราต้องการลบ Object$productออกจากฐานข้อมูล$entityManager->flush();สั่งให้EntityManagerลบข้อมูลออกจากฐานข้อมูล
ข้อควรระวัง: การลบข้อมูลเป็นการกระทำที่ไม่สามารถย้อนกลับได้ ดังนั้นควรตรวจสอบให้แน่ใจก่อนที่จะทำการลบข้อมูลจริง
แนวปฏิบัติที่ดี: ในบางกรณี แทนที่จะลบข้อมูลจริง อาจจะใช้วิธีการ "Soft Delete" แทน โดยการเพิ่ม Column เช่น deleted_at ในตาราง และเมื่อต้องการลบข้อมูล ก็เพียงแค่กำหนดค่าให้กับ Column นี้แทนที่จะลบ Record ออกจากตารางจริง ซึ่งจะช่วยให้เราสามารถกู้คืนข้อมูลที่ถูกลบไปแล้วได้ในภายหลัง
ในบทนี้ เราได้เรียนรู้วิธีการทำ CRUD Operations ด้วย ORM ซึ่งช่วยให้เราสามารถจัดการข้อมูลในฐานข้อมูลได้อย่างง่ายดายและมีประสิทธิภาพ ในบทถัดไป เราจะมาดูเรื่องความสัมพันธ์ระหว่าง Entity ซึ่งเป็นอีกหนึ่งหัวข้อที่สำคัญในการใช้งาน ORM