Symfony Doctrine ORM


在Symfony Web框架中,模型起着重要作用。他们是商业实体。它们由客户提供或从后端数据库中提取,根据业务规则进行操作并保存到数据库中。它们是Views呈现的数据。让我们在本章中了解模型以及它们如何与后端系统交互。

数据库模型

我们需要将我们的模型映射到后端关系数据库项目,以安全,高效地获取和保存模型。该映射可以使用对象关系映射(ORM)工具完成。Symfony提供了一个独立的软件包 DoctrineBundle ,它将Symfony与第三方PHP数据库ORM工具 Doctrine 集成在一起。

学说ORM

默认情况下,Symfony框架不提供任何组件来处理数据库。但是,它与 Doctrine ORM 紧密集成。Doctrine包含用于数据库存储和对象映射的多个PHP库。

以下示例将帮助您了解Doctrine的工作原理,如何配置数据库以及如何保存和检索数据。

学说ORM示例

在这个例子中,我们将首先配置数据库并创建一个Student对象,然后在其中执行一些操作。

为此,我们需要遵循以下步骤。

第1步:创建一个Symfony应用程序

使用以下命令创建一个Symfony应用程序, dbsample

symfony新的dbsample

第2步:配置数据库

通常,数据库信息在“app / config / parameters.yml”文件中配置。

打开文件并添加以下更改。

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

现在,Doctrine ORM可以连接到数据库。

第3步:创建数据库

发出以下命令以生成“studentsdb”数据库。此步骤用于在Doctrine ORM中绑定数据库。

php bin/console doctrine:database:create

执行该命令后,它会自动生成一个空的“studentsdb”数据库。您可以在屏幕上看到以下回复。

Created database `studentsdb` for connection named default

第4步:地图信息

映射信息不过是“元数据”,它是一组规则,它将学生类及其属性映射到特定数据库表的方式确切地告知Doctrine ORM。

那么这个元数据可以用许多不同的格式来指定,包括YAML,XML,或者你可以使用注释直接传递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;
}

在这里,表名是可选的。如果未指定表名,则将根据实体类的名称自动确定。

第5步:绑定实体

Doctrine为您创建简单的实体类。它可以帮助你建立任何实体。

发出以下命令以生成实体。

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

然后你会看到下面的结果,实体将被更新。

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;
 }
}

第6步:映射验证

创建实体后,您应该使用以下命令验证映射。

php bin/console doctrine:schema:validate

它会产生以下结果 -

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

由于我们尚未创建学生表,因此实体不同步。让我们在下一步中使用Symfony命令创建学生表。

第7步:创建一个架构

Doctrine可以自动创建Student实体所需的所有数据库表。这可以使用以下命令完成。

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

执行该命令后,您可以看到以下响应。

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

该命令比较数据库的外观和实际外观,并执行将数据库架构更新到所需位置所需的SQL语句。

现在,再次使用以下命令验证模式。

php bin/console doctrine:schema:validate

它会产生以下结果 -

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

步骤8:吸气和吸气

如“绑定实体”部分所示,以下命令为Student类生成所有获取者和设置者。

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

第9步:将对象保存到数据库

现在,我们已经将Student实体映射到其对应的Student表。我们现在应该能够将Student对象保存到数据库中。将以下方法添加到该包的StudentController。

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());
 }
}

在这里,我们使用getManager()方法通过基本控制器的getDoctrine()访问教条管理器,然后使用教义管理器的persist()方法保存当前对象。 persist() 方法将该命令添加到队列中,但 flush() 方法执行实际工作(保留学生对象)。

第10步:从数据库获取对象

在StudentController中创建一个将显示学生详细信息的函数。

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

第11步:创建一个视图

让我们创建一个指向显示操作的视图。转到views目录并创建一个文件“display.html.twig”。在文件中添加以下更改。

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>

您可以通过在浏览器中请求URL“http:// localhost:8000 / student / display”来获得结果。

它将在屏幕上产生以下输出 -

创建视图

第12步:更新对象

要更新StudentController中的对象,请创建一个操作并添加以下更改。

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

现在,请求URL“http:// localhost:8000 / Student / update / 1”,它会产生以下结果。

它将在屏幕上产生以下输出 -

更新对象

第13步:删除一个对象

删除一个对象是相似的,它需要调用实体(doctrine)管理器的remove()方法。

这可以使用以下命令完成。

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