- Symfony 教程
- Symfony - 首页
- Symfony - 简介
- Symfony - 安装
- Symfony - 架构
- Symfony - 组件
- Symfony - 服务容器
- Symfony - 事件 & 事件监听器
- Symfony - 表达式
- Symfony - 捆绑包
- 创建简单的 Web 应用程序
- Symfony - 控制器
- Symfony - 路由
- Symfony - 视图引擎
- Symfony - Doctrine ORM
- Symfony - 表单
- Symfony - 验证
- Symfony - 文件上传
- Symfony - Ajax 控制
- Cookie & 会话管理
- Symfony - 国际化
- Symfony - 日志记录
- Symfony - 邮件管理
- Symfony - 单元测试
- Symfony - 高级概念
- Symfony - REST 版本
- Symfony - CMF 版本
- 完整的运行示例
- Symfony 有用资源
- Symfony - 快速指南
- Symfony - 有用资源
- Symfony - 讨论
Symfony - Doctrine ORM
在 Symfony Web 框架中,模型扮演着重要的角色。它们是业务实体。它们要么由客户提供,要么从后端数据库中获取,根据业务规则进行操作并持久化回数据库。它们是由视图呈现的数据。在本节中,让我们了解模型以及它们如何与后端系统交互。
数据库模型
我们需要将我们的模型映射到后端关系数据库项,以便安全有效地获取和持久化模型。可以使用对象关系映射 (ORM) 工具来完成此映射。Symfony 提供了一个单独的捆绑包,**DoctrineBundle**,它将 Symfony 与第三方 PHP 数据库 ORM 工具 **Doctrine** 集成。
Doctrine ORM
默认情况下,Symfony 框架不提供任何用于处理数据库的组件。但是,它与 **Doctrine ORM** 紧密集成。Doctrine 包含多个用于数据库存储和对象映射的 PHP 库。
以下示例将帮助您了解 Doctrine 的工作原理,如何配置数据库以及如何保存和检索数据。
Doctrine ORM 示例
在本示例中,我们将首先配置数据库并创建一个 Student 对象,然后在其上执行一些操作。
为此,我们需要遵循以下步骤。
步骤 1:创建 Symfony 应用程序
使用以下命令创建一个名为 **dbsample** 的 Symfony 应用程序。
symfony new 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 Student 类及其属性如何映射到特定的数据库表。
嗯,此元数据可以用多种不同的格式指定,包括 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
由于我们尚未创建 students 表,因此实体不同步。让我们在下一步中使用 Symfony 命令创建 students 表。
步骤 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:Getter 和 Setter
如“绑定实体”部分所示,以下命令将为 Student 类生成所有 Getter 和 Setter。
$ 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());
}
}
在这里,我们通过基本控制器的 getDoctrine() 使用 getManager() 方法访问了 doctrine 管理器,然后使用 doctrine 管理器的 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“https://: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“https://: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!');
}