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!');
}