Symfony - Học thuyết ORM

Trong khuôn khổ web Symfony, mô hình đóng một vai trò quan trọng. Họ là các thực thể kinh doanh. Chúng được cung cấp bởi khách hàng hoặc được tìm nạp từ cơ sở dữ liệu back-end, được thao tác theo các quy tắc nghiệp vụ và tồn tại trở lại cơ sở dữ liệu. Chúng là dữ liệu được trình bày bởi Chế độ xem. Hãy để chúng tôi tìm hiểu về các mô hình và cách chúng tương tác với hệ thống back-end trong chương này.

Mô hình cơ sở dữ liệu

Chúng ta cần ánh xạ các mô hình của mình tới các mục cơ sở dữ liệu quan hệ back-end để tìm nạp và duy trì các mô hình một cách an toàn và hiệu quả. Ánh xạ này có thể được thực hiện bằng công cụ Ánh xạ quan hệ đối tượng (ORM). Symfony cung cấp một gói riêng biệt,DoctrineBundle, tích hợp Symfony với công cụ ORM cơ sở dữ liệu PHP của bên thứ ba, Doctrine.

Giáo lý ORM

Theo mặc định, khung công tác Symfony không cung cấp bất kỳ thành phần nào để hoạt động với cơ sở dữ liệu. Tuy nhiên, nó tích hợp chặt chẽ vớiDoctrine ORM. Doctrine chứa một số thư viện PHP được sử dụng để lưu trữ cơ sở dữ liệu và ánh xạ đối tượng.

Ví dụ sau sẽ giúp bạn hiểu cách hoạt động của Doctrine, cách cấu hình cơ sở dữ liệu và cách lưu và truy xuất dữ liệu.

Ví dụ về học thuyết ORM

Trong ví dụ này, trước tiên chúng ta sẽ cấu hình cơ sở dữ liệu và tạo một đối tượng Student, sau đó thực hiện một số thao tác trong đó.

Để làm được điều này chúng ta cần tuân thủ các bước sau.

Bước 1: Tạo ứng dụng Symfony

Tạo một ứng dụng Symfony, dbsample bằng cách sử dụng lệnh sau.

symfony new dbsample

Bước 2: Định cấu hình cơ sở dữ liệu

Nói chung, thông tin cơ sở dữ liệu được định cấu hình trong tệp “app / config / parameter.yml”.

Mở tệp và thêm các thay đổi sau.

parameter.yml

parameters: 
   database_host: 127.0.0.1 
   database_port: null
   database_name: studentsdb 
   database_user: <user_name> 
   database_password: <password> 
   mailer_transport: smtp 
   mailer_host: 127.0.0.1 
   mailer_user: null 
   mailer_password: null 
   secret: 037ab82c601c10402408b2b190d5530d602b5809 
   
   doctrine: 
      dbal: 
      driver:   pdo_mysql 
      host:     '%database_host%' 
      dbname:   '%database_name%' 
      user:     '%database_user%' 
      password: '%database_password%' 
      charset: utf8mb4

Bây giờ, Doctrine ORM có thể kết nối với cơ sở dữ liệu.

Bước 3: Tạo cơ sở dữ liệu

Đưa ra lệnh sau để tạo cơ sở dữ liệu “studentdb”. Bước này được sử dụng để liên kết cơ sở dữ liệu trong Doctrine ORM.

php bin/console doctrine:database:create

Sau khi thực hiện lệnh, nó sẽ tự động tạo ra một cơ sở dữ liệu “studentdb” trống. Bạn có thể thấy phản hồi sau trên màn hình của mình.

Created database `studentsdb` for connection named default

Bước 4: Thông tin bản đồ

Thông tin ánh xạ không có gì khác ngoài "siêu dữ liệu". Nó là một tập hợp các quy tắc thông báo cho Doctrine ORM chính xác cách lớp Sinh viên và các thuộc tính của nó được ánh xạ tới một bảng cơ sở dữ liệu cụ thể.

Chà, siêu dữ liệu này có thể được chỉ định ở một số định dạng khác nhau, bao gồm YAML, XML hoặc bạn có thể trực tiếp vượt qua lớp Sinh viên bằng cách sử dụng chú thích. Nó được định nghĩa như sau.

Student.php

Thêm các thay đổi sau vào tệp.

<?php  
namespace AppBundle\Entity;  

use Doctrine\ORM\Mapping as ORM;  
/** 
   * @ORM\Entity 
   * @ORM\Table(name = "students") 
*/ 
class Student { 
   /** 
      * @ORM\Column(type = "integer") 
      * @ORM\Id 
      * @ORM\GeneratedValue(strategy = "AUTO") 
   */ 
   private $id;  
    
   /** 
      * @ORM\Column(type = "string", length = 50) 
   */ 
   private $name;  
   
   /** 
     * @ORM\Column(type = "text") 
     */ 
   private $address; 
}

Ở đây, tên bảng là tùy chọn. Nếu tên bảng không được chỉ định, thì nó sẽ được xác định tự động dựa trên tên của lớp thực thể.

Bước 5: Ràng buộc một thực thể

Doctrine tạo các lớp thực thể đơn giản cho bạn. Nó giúp bạn xây dựng bất kỳ thực thể nào.

Đưa ra lệnh sau để tạo một thực thể.

php bin/console doctrine:generate:entities AppBundle/Entity/Student

Sau đó, bạn sẽ thấy kết quả sau và thực thể sẽ được cập nhật.

Generating entity "AppBundle\Entity\Student" 
   > backing up Student.php to Student.php~ 
   > generating AppBundle\Entity\Student

Student.php

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM;  
/** 
   * @ORM\Entity 
   * @ORM\Table(name="students") 
*/ 
class Student { 
   /** 
      * @ORM\Column(type="integer") 
      * @ORM\Id 
      * @ORM\GeneratedValue(strategy="AUTO") 
   */ 
   private $id;  
    
   /** 
      * @ORM\Column(type = "string", length = 50) 
   */ 
   private $name; 
    
   /** 
      * @ORM\Column(type = "text") 
   */
   private $address; 
    
   /** 
      * Get id 
      * 
      * @return integer 
   */ 
   public function getId() { 
      return $this->id; 
   }  
    
   /** 
      * Set name 
      * 
      * @param string $name 
      * 
      * @return Student 
   */ 
    
   public function setName($name) { 
      $this->name = $name;  
      return $this; 
   }  
    
   /** 
      * Get name 
      * 
      * @return string 
   */ 
    
   public function getName() { 
      return $this->name; 
   }  
    
   /**
      * Set address 
      * 
      * @param string $address 
      * 
      * @return Student 
   */ 
    
   public function setAddress($address) { 
      $this->address = $address;  
      return $this; 
   }  
    
   /** 
      * Get address 
      * 
      * @return string 
   */ 
   
   public function getAddress() { 
      return $this->address; 
   } 
}

Bước 6: Xác thực bản đồ

Sau khi tạo các thực thể, bạn nên xác thực các ánh xạ bằng lệnh sau.

php bin/console doctrine:schema:validate

Nó sẽ tạo ra kết quả sau:

[Mapping]  OK - The mapping files are correct. 
[Database] FAIL - The database schema is not in sync with the current mapping file

Vì chúng tôi chưa tạo bảng sinh viên nên thực thể không đồng bộ. Hãy để chúng tôi tạo bảng sinh viên bằng lệnh Symfony trong bước tiếp theo.

Bước 7: Tạo một lược đồ

Doctrine có thể tự động tạo tất cả các bảng cơ sở dữ liệu cần thiết cho thực thể Student. Điều này có thể được thực hiện bằng cách sử dụng lệnh sau.

php bin/console doctrine:schema:update --force

Sau khi thực hiện lệnh, bạn có thể thấy phản hồi sau.

Updating database schema... 
Database schema updated successfully! "1" query was executed

Lệnh này so sánh cơ sở dữ liệu của bạn trông như thế nào với nó thực sự trông như thế nào và thực thi các câu lệnh SQL cần thiết để cập nhật lược đồ cơ sở dữ liệu về vị trí của nó.

Bây giờ, hãy xác thực lại lược đồ bằng lệnh sau.

php bin/console doctrine:schema:validate

Nó sẽ tạo ra kết quả sau:

[Mapping]  OK - The mapping files are correct. 
[Database] OK - The database schema is in sync with the mapping files

Bước 8: Getter và setter

Như đã thấy trong phần Bind an Entity, lệnh sau tạo tất cả getters và setters cho lớp Sinh viên.

$ php bin/console doctrine:generate:entities AppBundle/Entity/Student

Bước 9: Duy trì các đối tượng vào cơ sở dữ liệu

Bây giờ, chúng tôi đã ánh xạ thực thể Sinh viên vào bảng Sinh viên tương ứng của nó. Bây giờ chúng ta có thể duy trì các đối tượng Student vào cơ sở dữ liệu. Thêm phương thức sau vào StudentController của gói.

StudentController.php

<?php  
namespace AppBundle\Controller; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response;  
use AppBundle\Entity\Student; 

class StudentController extends Controller { 
   /** 
      * @Route("/student/add") 
   */ 
   public function addAction() { 
      $stud = new Student(); 
      $stud->setName('Adam'); 
      $stud->setAddress('12 north street'); 
      $doct = $this->getDoctrine()->getManager();
      
      // tells Doctrine you want to save the Product 
      $doct->persist($stud);
      
      //executes the queries (i.e. the INSERT query) 
      $doct->flush(); 
      
      return new Response('Saved new student with id ' . $stud->getId()); 
   } 
}

Ở đây, chúng ta đã truy cập trình quản lý học thuyết bằng cách sử dụng phương thức getManager () thông qua getDoctrine () của bộ điều khiển cơ sở và sau đó duy trì đối tượng hiện tại bằng cách sử dụng phương thức Kiên trì () của trình quản lý học thuyết. persist() phương thức thêm lệnh vào hàng đợi, nhưng flush() phương pháp làm việc thực tế (kiên trì đối tượng học sinh).

Bước 10: Tìm nạp đối tượng từ cơ sở dữ liệu

Tạo một hàm trong StudentController sẽ hiển thị thông tin chi tiết của học sinh.

StudentController.php

/** 
   * @Route("/student/display") 
*/ 
public function displayAction() { 
   $stud = $this->getDoctrine() 
   ->getRepository('AppBundle:Student') 
   ->findAll();
   return $this->render('student/display.html.twig', array('data' => $stud)); 
}

Bước 11: Tạo chế độ xem

Hãy tạo một dạng xem trỏ đến hành động hiển thị. Di chuyển đến thư mục khung nhìn và tạo tệp “display.html.twig”. Thêm các thay đổi sau vào tệp.

display.html.twig

<style> 
   .table { border-collapse: collapse; } 
   .table th, td { 
      border-bottom: 1px solid #ddd; 
      width: 250px; 
      text-align: left; 
      align: left; 
   } 
</style> 

<h2>Students database application!</h2>  
<table class = "table">  
   <tr>  
      <th>Name</th>  
      <th>Address</th>  
   </tr>  
   {% for x in data %} 
   <tr>  
      <td>{{ x.Name }}</td>   
      <td>{{ x.Address }}</td>   
   </tr>  
   {% endfor %} 
</table>

Bạn có thể nhận được kết quả bằng cách yêu cầu URL “http: // localhost: 8000 / student / display” trong trình duyệt.

Nó sẽ tạo ra kết quả sau trên màn hình:

Bước 12: Cập nhật một đối tượng

Để cập nhật một đối tượng trong StudentController, hãy tạo một hành động và thêm các thay đổi sau.

/** 
   * @Route("/student/update/{id}") 
*/ 
public function updateAction($id) { 
   $doct = $this->getDoctrine()->getManager(); 
   $stud = $doct->getRepository('AppBundle:Student')->find($id);  
   
   if (!$stud) { 
      throw $this->createNotFoundException( 
         'No student found for id '.$id 
      ); 
   } 
   $stud->setAddress('7 south street'); 
   $doct->flush(); 
   
   return new Response('Changes updated!'); 
}

Bây giờ, hãy yêu cầu URL “http: // localhost: 8000 / Student / update / 1” và nó sẽ cho ra kết quả như sau.

Nó sẽ tạo ra kết quả sau trên màn hình:

Bước 13: Xóa đối tượng

Việc xóa một đối tượng cũng tương tự và nó yêu cầu một lệnh gọi đến phương thức remove () của trình quản lý thực thể (học thuyết).

Điều này có thể được thực hiện bằng cách sử dụng lệnh sau.

/** 
   * @Route("/student/delete/{id}") 
*/ 
public function deleteAction($id) { 
   $doct = $this->getDoctrine()->getManager(); 
   $stud = $doct->getRepository('AppBundle:Student')->find($id);  
    
   if (!$stud) { 
      throw $this->createNotFoundException('No student found for id '.$id); 
   }  
    
   $doct->remove($stud); 
   $doct->flush();  
   
   return new Response('Record deleted!'); 
}