symfony mysql_数据库和Doctrine ORM

对于任何应用程序来说,一个最常见和最具挑战的任务,就是从数据库中读取和持久化数据信息。尽管symfony框架并未整合任何需要使用数据库的组件,但是却紧密集成了一个名为 Doctrine 的三方类库。Doctrine的主要目标是为你提供一个强有力的工具,令数据库互动更加轻松和灵活。

在本章,你将学习如何在Symfony项目中利用doctrine来提供丰富的数据库互动。

Note

Doctrine与symfony是完全解耦的,使用与否是可选的。本章讲的全部是Doctrine ORM,目的是让你把对象映射到关系型数据库中(如 MySQL, PostgreSQL 和 Microsoft SQL)。如果你倾向于使用数据库的原始查询,这很简单,可参考 如何使用Doctrine DBAL 一文的讲解。

你也可以使用Doctrine ODM类库将数据持久化到 MongoDB。参考 DoctrineMongoDBBundle 以了解更多信息。

简单例子:一件产品(Product) ¶

要了解Doctrine是如何工作的,最简单的方式就是看一个实际应用。在本节,你需要配置你的数据库,创建一个 Product 对象,把它持久化到数据库,再取回它。

配置数据库 ¶

真正开始之前,你需要配置你的数据库连接信息。按照惯例,这部分信息通常配置在 app/config/parameters.yml 文件中:

1

2

3

4

5

6

7

8# app/config/parameters.ymlparameters:database_host: localhostdatabase_name: test_projectdatabase_user: rootdatabase_password: password

# ...

Note

通过 parameters.yml 来定义配置,只是一个惯例。配置Doctrine时,定义在那个文件中的参数,将被主配置文件引用:

1

2

3

4

5

6

7

8# app/config/config.ymldoctrine:dbal:driver: pdo_mysqlhost: "%database_host%"dbname: "%database_name%"user: "%database_user%"password:"%database_password%"

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:doctrine="http://symfony.com/schema/dic/doctrine"

xsi:schemaLocation="http://symfony.com/schema/dic/services

http://symfony.com/schema/dic/services/services-1.0.xsd

http://symfony.com/schema/dic/doctrine

http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">

driver="pdo_mysql"

host="%database_host%"

dbname="%database_name%"

user="%database_user%"

password="%database_password%" />

1

2

3

4

5

6

7

8

9

10// app/config/config.php

$configuration->loadFromExtension('doctrine', array(

'dbal' => array(

'driver' => 'pdo_mysql',

'host' => '%database_host%',

'dbname' => '%database_name%',

'user' => '%database_user%',

'password' => '%database_password%',

),

));

通过把数据库信息分离到一个单独文件中,你可以很容易地为每个服务器保存不同的版本。你还可以在项目外轻松存储数据库配置(或任何敏感信息),举例来说,就和apache中的配置信息一样。参考 服务容器外部参数如何设置 以了解更多。

现在Doctrine可以连接你的数据库了,下面的命令可以自动生成一个空的 test_project 数据库:

1$ php bin/console doctrine:database:create

设置数据库为UTF8

Symfony项目开始后,老练的程序员也会犯的一个错误是,忘了设置他们的数据库默认字符集和校对规则(charset and collation),最终变成latin类型,也就是多数数据库默认的。他们也许在第一次操作时会记得,但在后面的开发中敲打两行相关的常用命令之后就完全忘掉了:

1

2$ php bin/console doctrine:database:drop --force

$ php bin/console doctrine:database:create

设置UTF8为MySQL的默认字符集简单到只要在配置文件(一般是my.cnf文件)中加几行代码就可以了:

1

2

3

4[mysqld]

#Version 5.5.3 introduced "utf8mb4", which is recommended

collation-server =utf8mb4_general_ci # Replaces utf8_general_ci

character-set-server =utf8mb4 # Replaces utf8

你还可以改变Doctrine的默认字符集,以便生成的SQL使用设置正确的字符集。

1

2

3

4

5

6

7# app/config/config.ymldoctrine:dbal:charset:utf8mb4default_table_options:charset:utf8mb4collate:utf8mb4_unicode_ci

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:doctrine="http://symfony.com/schema/dic/doctrine"

xsi:schemaLocation="http://symfony.com/schema/dic/services

http://symfony.com/schema/dic/services/services-1.0.xsd

http://symfony.com/schema/dic/doctrine

http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">

charset="utf8mb4">

utf8mb4

utf8mb4_unicode_ci

1

2

3

4

5

6

7

8

9

10// app/config/config.php

$configuration->loadFromExtension('doctrine', array(

'dbal' => array(

'charset' => 'utf8mb4',

'default_table_options' => array(

'charset' => 'utf8mb4'

'collate' => 'utf8mb4_unicode_ci'

)

),

));

我们推荐避免使用Mysql的 uft8 字符集,因为它并不兼容4-byte unicode字符,如果字符串中有这种字符会被清空。不过这种情况被修复了,参考 新型utf8mb4字符集。

Note

如果你要用SQLite作为数据库,在path选项中设置你的数据库路径:

1

2

3

4

5

6# app/config/config.ymldoctrine:dbal:driver:pdo_sqlitepath:"%kernel.root_dir%/sqlite.db"charset:UTF8

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:doctrine="http://symfony.com/schema/dic/doctrine"

xsi:schemaLocation="http://symfony.com/schema/dic/services

http://symfony.com/schema/dic/services/services-1.0.xsd

http://symfony.com/schema/dic/doctrine

http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">

driver="pdo_sqlite"

path="%kernel.root_dir%/sqlite.db"

charset="UTF-8" />

1

2

3

4

5

6

7

8// app/config/config.php

$container->loadFromExtension('doctrine', array(

'dbal' => array(

'driver' => 'pdo_sqlite',

'path' => '%kernel.root_dir%/sqlite.db',

'charset' => 'UTF-8',

),

));

创建一个Entity类 ¶

假设你正构建一套程序,其中有些产品需要展示。即使不考虑Doctrine或者数据库,你也已经知道你需要一个 Product 对象来呈现这些产品。在你AppBundle的 Entity 目录下创建这个类:

1

2

3

4

5

6

7

8

9// src/AppBundle/Entity/Product.php

namespace AppBundle\Entity;

class Product

{

private $name;

private $price;

private $description;

}

这个类——常被称作一个“Entity”,表示 一个保存着数据的基本类 ——它很简单,可以满足程序中所需产品的业务需求。这个类还不能被保存到数据库中——它只是个简单的PHP类。

Tip

一旦你学习了Doctrine背后的概念,你可以让Doctrine为你创建entity类。它将问你一些互动问题来帮你创建任意的entity:

1$ php bin/console doctrine:generate:entity

添加映射信息 ¶

Doctrine允许你以一种更加有趣的方式来使用数据库,而不只是把标量数据的行(rows)取出到数组中。Doctrine允许你从数据库中取出整个 对象,同时持久化整个对象到数据库中。对Doctrine来说要实现这些,你必须 映射 数据表到特定的PHP类中,那些表的列(columns)必须被映射为相应PHP类的特定属性。

42d4410336e8f9e66e91c9bc0049022b.png

你要以“元数据(meatdata)”形式来提供这些映射信息,有一组规则可以准确告之Doctrine Product 类及其属性应该如何 映射到 一个特定的数据表。这个metadata可以通过不同的格式来指定,包括YAML,XML或者通过DocBlock注释(译注:annotations)直接定义到 Product 类中:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33// src/AppBundle/Entity/Product.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**

* @ORM\Entity

* @ORM\Table(name="product")

*/

class Product

{

/**

* @ORM\Column(type="integer")

* @ORM\Id

* @ORM\GeneratedValue(strategy="AUTO")

*/

private $id;

/**

* @ORM\Column(type="string", length=100)

*/

private $name;

/**

* @ORM\Column(type="decimal", scale=2)

*/

private $price;

/**

* @ORM\Column(type="text")

*/

private $description;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17# src/AppBundle/Resources/config/doctrine/Product.orm.ymlAppBundle\Entity\Product:type:entitytable:productid:id:type:integergenerator:{ strategy:AUTO }fields:name:type:stringlength:100price:type:decimalscale:2description:type:text

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping

http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

Note

一个bundle只可以接受一种metadata的定义格式。比如,不能把YAML的metadata定义和添加了注释(annotation)的PHP entity类混用。

Tip

表名是可选的,如果省略,将自动取决于entity类的名称。

Doctrine允许你选择广泛的字段类型,每一种都有自己的配置。可用字段类型的信息,参考 Doctrine字段类型参考。

Seealso

你也可以查看Doctrine官方文档 Basic Mapping Documentation 以了解关于映射的所有细节信息。如果你使用annotation,你需要为所有annotation加挂 ORM\ (例如 ORM\Column(...) ),这在Doctrine文档中并未写明。你还需要去包容 use Doctrine\ORM\Mapping as ORM; 声明,它可以 import(导入) ORM annotation前缀。

Caution

小心Entity类名(或者其属性)同时也是一个SQL保留的关键字(如 group 和 user )。例如,如果你的entity类名称为 Group ,那么,默认时,你的表名将会是group,这在一些数据库引擎中可能导致SQL错误。参考 Reserved SQL keywords documentation 以了解如何正确规避这些名称。可选地,你可以任意选择数据库的schema,轻松映射成不同的表名或列名。参考 Creating Classes for the Database 和 Property Mapping文档。

Note

当使用其他一些“使用了annotations”的类库或者程序(如Doxygen)时,你应该把 @IgnoreAnnotation 注释添加到类中,来指示Symfony应该忽略哪个annotation。

例如,要避免 @fn annotation抛出异常,添加下列注释:

1

2

3

4

5/**

* @IgnoreAnnotation("fn")

*/

class Product

// ...

Tip

创建entity之后,你应该使用以下命令来验证映射(mappings):

1$ php bin/console doctrine:schema:validate

生成Getters和Setters ¶

尽管Doctrine现在知道了如何持久化 Product 对象到数据库,但是类本身还不具备真正用途。因为 Product 仅仅是一个带有 private 属性的常规PHP类,你需要创建 public 的getter和setter方法(比如 getName() , setName($name) )以便在程序其他部分来访问它的属性(其属性是protected)。幸运的是,下面的命令可以自动生成这些模板化的方法:

1$ php bin/console doctrine:generate:entities AppBundle/Entity/Product

该命令可以确保 Product 类所有的getter和setter都被生成。这是一个安全的命令行——你可以多次运行它,它只会生成那些不存在的getters和setters(即,不会替换已有的方法)。

Caution

重要提示

下面这句话极其深刻,乃是活用Doctrine的关键。大家一定照做。

记得,doctrine entity generator生成的是简单的getters/setters。你应该复审那些已生成的方法,在必要时,添加逻辑进去,以满足你的程序之需求。

关于 doctrine:generate:entities 的更多内容

使用 doctrine:generate:entities 命令你可以:

在entity类中生成getters和setters;

在entity类配置了 @ORM\Entity(repositoryClass=”…”) annotation的情况下生成所对应的repository类;

为 1:n 或 n:m 生成合适的构造器。

doctrine:generate:entities 命令会保存原始 Product.php 文件的备份并命名为 Product.php~ 。 有些时候这个文件可能会引发“Cannot redeclare class”错误。它可以被安全删除。你还可以使用 –no-backup 选项,来防止生成这些备份文件。

注意,你并不 需要 (依赖于)此命令。你也可以手写getters和setters。这个选项的存在只是为了节省你的时间,因为在开发过程中创建这些方法是一个常见任务。

你也可以为一个bundle或者一个entity命名空间内的所有已知实体(任何包含Doctrine映射信息的PHP类)来生成getter和setter:

1

2

3

4

5

6

7# generates all entities in the AppBundle

# 生成AppBundle下的全部entities

$ php bin/console doctrine:generate:entities AppBundle

# generates all entities of bundles in the Acme namespace

# 生成Acme命名空间下的bundles的全部entities

$ php bin/console doctrine:generate:entities Acme

创建数据表/Schema ¶

现在你有了一个包含映射信息的可用 Product 类,因此Doctrine确切地知道如何持久化它。当然,你还没有相应的 product 数据表在库中。幸运的是,Doctrine可以自动创建所有的数据表。要这么做,运行以下命令:

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

Tip

说真的,这条命令出奇的强大。它会比较你的数据库 理论上应该是 什么样子的(基于你的entities的映射信息)以及 实际上 它应该是什么样,然后执行所需的SQl语句来将数据库的schema 更新到 它所应有的样子。换句话说,如果你添加了一个包含“映射元数据”(mapping metadata)的新属性到 Product 并运行此任务,它将执行所需的 "ALTER TABLE" 语句,向已经存在的 product 表添加那个新列。

一个利用此功能之优势的更佳方式是通过 migrations,它允许你生成这些SQL语句,并把它们并存储到migration类中,这些类能够有序运行在你的生产环境中,进而安全可靠地更新和追踪数据库的schema改变。

不管你是否利用了数据库迁移,doctrine:schema:update 命令只适合在开发环境中使用。它不应该被用于生产环境。

现在你的数据库中有了一个全功能的product表,它的列与你指定的元数据相匹配。

持久化对象到数据库 ¶

现在你有了一个Product实体和与之映射的product数据库表。你可以把数据持久化到数据库里。在Controller内,它非常简单。添加下面的方法到bundle的DefaultController中。

现在你已经把 Product entity 映射到与之对应的 product 表中,你已经准备好把 Product 对象持久化到数据库中。在控制器里面,这极其简单。向bundle的 DefaultController 添加以下方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26// src/AppBundle/Controller/DefaultController.php

// ...

use AppBundle\Entity\Product;

use Symfony\Component\HttpFoundation\Response;

// ...

public function createAction()

{

$product = new Product();

$product->setName('Keyboard');

$product->setPrice(19.99);

$product->setDescription('Ergonomic and stylish!');

$em = $this->getDoctrine()->getManager();

// tells Doctrine you want to (eventually) save the Product (no queries yet)

// 告诉Doctrine你希望(最终)存储Product对象(还没有语句执行)

$em->persist($product);

// actually executes the queries (i.e. the INSERT query)

// 真正执行语句(如,INSERT 查询)

$em->flush();

return new Response('Saved new product with id '.$product->getId());

}

Note

如果你正在跟进本例程,需要创建一个路由,并指向这个action,才能看到它运行。

Tip

本例展示了在控制器中使用Doctrine的 getDoctrine() 方法。这是取出 doctrine 服务的快捷方法。若你在服务中注入此服务,即可在任意地方使用doctrine。参考 服务容器 以了解更多创建服务之内容。

深入分析一下前面的例子:

10-13行 在此处实例化,并且像其他常规PHP对象一样去使用 $product 对象。

15行 这一行取出了Doctrine的 entity manager 对象,它负责处理数据库的持久化(译注:写入)和取出对象的过程。

18行 persist($product) 调用,告诉Doctrine去 "管理" $product 对象。它 没有 引发对数据库的请求。

21行 当 flush() 方法被调用时,Doctrine会遍历它管理的所有对象以确定是否需要被持久化到数据库。本例中, $product 对象的数据在库中并不存在,因此entity manager要执行 INSERT 请求,在 product 表中创建一个新行。

Note

事实上,由于Doctrine了解你的全部被管理的实体,当你调用 flush() 方法时,它会计算出所有的变更集合(changeset),并按正确顺序执行语句。它利用准备好的缓存语句以略微提高性能。比如,你要持久化总数为100的 Product 对象,然后调用 flush() 方法,Doctrine将用一个单一的prepare语法对象,来执行100次 INSERT 请求。

Note

如果 flush() 调用失败,一个 Doctrine\ORM\ORMException 异常会被抛出。参考 Transactions and Concurrency(处理和并发)。

在创建和更新对象时,工作流是相同的。在下一小节你将看到,如果记录已经存在于数据库中,Doctrine是如何聪明地自动发出一个 Update 语句的。

Tip

Doctrine提供了一个类库,允许你程序化地加载测试数据到你的项目中(即,"fixture data",固定的数据)。参考 DoctrineFixturesBundle 以了解更多。

从数据库中获取对象 ¶

从数据库中取回对象就更简单了,举个例子,假如你配置了一个路由,基于产品的 id 来显示特定的 Product 对象:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15public function showAction($productId)

{

$product = $this->getDoctrine()

->getRepository('AppBundle:Product')

->find($productId);

if (!$product) {

throw $this->createNotFoundException(

'No product found for id '.$productId

);

}

// ... do something, like pass the $product object into a template

// ... 做一些事,比如把 $product 对象传入模板

}

Tip

你可以使用 @ParamConverter 快捷注释,毋须编写任何代码即可实现同样的功能。参考 FrameworkExtraBundle 以了解更多。

当你要查询某个特定类型的对象时,你总是要使用它的”respository”(宝库)。你可以认为Respository是一个PHP类,它的唯一工作就是帮助你从那个特定的类中取出entity。对于一个entity类,要访问其宝库,通过:

1

2$repository = $this->getDoctrine()

->getRepository('AppBundle:Product');

Note

appBundle:Product 是快捷写法,你可以在Doctrine里随处使用,以替代entity类的FQCN类名(如 AppBundle\Entity\Product )。只要你的entity存放在bundle的 Entity 命名空间下,它就会工作。

一旦有了Repository对象,你就可以访问它的全部有用的方法了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17$repository = $this->getDoctrine()->getRepository('AppBundle:Product');

// query for a single product by its primary key (usually "id")

// 通过主键(通常是id)查询一件产品

$product = $repository->find($productId);

// dynamic method names to find a single product based on a column value

// 动态方法名称,基于字段的值来找到一件产品

$product = $repository->findOneById($productId);

$product = $repository->findOneByName('Keyboard');

// dynamic method names to find a group of products based on a column value

// 动态方法名称,基于字段值来找出一组产品

$products = $repository->findByPrice(19.99);

// find *all* products / 查出 *全部* 产品

$products = $repository->findAll();

Note

当然,你也可以使用复杂的查询,参考 对象查询 小节 。

你也可以有效利用 findBy 和 findOneBy 方法,基于多个条件来轻松获取对象:

1

2

3

4

5

6

7

8

9

10

11

12

13

14$repository = $this->getDoctrine()->getRepository('AppBundle:Product');

// query for a single product matching the given name and price

// 查询一件产品,要匹配给定的名称和价格

$product = $repository->findOneBy(

array('name' => 'Keyboard', 'price' => 19.99)

);

// query for multiple products matching the given name, ordered by price

// 查询多件产品,要匹配给定的名称和价格

$products = $repository->findBy(

array('name' => 'Keyboard'),

array('price' => 'ASC')

);

Tip

渲染任何页面时,你可以在除错工具条(web debug toolbar)的右下角看到许多查询。

9af6436e185b7e929ce4615430b46472.png

如果你点击图标,分析器(profiler)将会打开,显示出所产生的精确查询。

如果你的页面查询超过了50个,图标会变成黄色。这表明某些地方不大对劲。

对象更新 ¶

一旦从Doctrine中获取了一个对象,更新它就很容易了。假设你有一个路由,把一个产品id映射到controller的updateaction:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16public function updateAction($productId)

{

$em = $this->getDoctrine()->getManager();

$product = $em->getRepository('AppBundle:Product')->find($productId);

if (!$product) {

throw $this->createNotFoundException(

'No product found for id '.$productId

);

}

$product->setName('New product name!');

$em->flush();

return $this->redirectToRoute('homepage');

}

更新一个对象包括三步:

从Doctrine中取出对象;

修改对象;

调用entity manager的 flush() 方法。

注意调用 $em->persist($product) 是不必要的。回想一下,这个方法只是告诉Doctrine去管理或者“观察” $product 对象。此处,因为你已经取到了 $product 对象了,它已经被管理了。

删除对象 ¶

删除一个对象十分类似,但需要从entity manager调用 remove() 方法:

1

2$em->remove($product);

$em->flush();

你可能已经预期,remove() 方法通知Doctrine你想从数据库中删除指定的entity。真正的 DELETE 查询不会被真正执行,直到 flush() 方法被调用。

对象查询 ¶

你已经看到repository对象是如何让你执行一些基本查询而毋须做任何工作了:

1

2

3

4$repository = $this->getDoctrine()->getRepository('AppBundle:Product');

$product = $repository->find($productId);

$product = $repository->findOneByName('Keyboard');

当然,Doctrine 也允许你使用Doctrine Query Language(DQL)来写一些复杂的查询,DQL类似于SQL,只是它用于查询一个或者多个entity类的对象(如 product),而SQL则是查询一个数据表中的行(如 product )。

在Doctrine中查询时,你有两个主要选择:编写纯正的Doctrine查询(DQL) 或者 使用Doctrine的Query Builder。

使用DQL进行对象查询 ¶

假设你要查询价格高于 19.99 的产品,并且按价格从低到高排列。你可以使用DQL,Doctrine中类似原生SQL的语法,来构造一个用于此场景的查询:

1

2

3

4

5

6

7

8

9$em = $this->getDoctrine()->getManager();

$query = $em->createQuery(

'SELECT p

FROM AppBundle:Product p

WHERE p.price > :price

ORDER BY p.price ASC'

)->setParameter('price', 19.99);

$products = $query->getResult();

如果你习惯了写SQL,那么对于DQL也会非常自然。它们之间最大的不同就是你需要就“select PHP对象”来进行思考,而不是数据表的行。正因为如此,你要 从 AppBundle:Product 这个 entity (可选的一个AppBundle\Entity\Product 类的快捷写法)来select,然后给entity一个 p 的别名。

Tip

注意 setParameter() 方法。当使用Doctrine时,通过“占位符”来设置任意的外部值(上面例子的 :price),是一个好办法,因为它可以防止SQL注入攻击。

getResult() 方法返回一个结果数组。要得到一个结果,可以使用getSingleResult()(这个方法在没有结果时会抛出一个异常)或者 getOneOrNullResult() :

1$product = $query->setMaxResults(1)->getOneOrNullResult();

DQL语法强大到令人难以置信,允许轻松地在entity之间进行join(稍后会覆盖relations)和group等。参考 Doctrine Query Language 文档以了解更多。

使用Doctrine's Query Builder进行对象查询 ¶

不去写DQL的大字符串,你可以使用一个非常有用的QueryBuilder对象,来构建那个字符串。当你的查询取决于动态条件时,这很有用,因为随着你的连接字符串不断增加,DQL代码会越来越难以阅读:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15$repository = $this->getDoctrine()

->getRepository('AppBundle:Product');

// createQueryBuilder() automatically selects FROM AppBundle:Product

// and aliases it to "p"

// createQueryBuilder() 自动从 AppBundle:Product 进行 select 并赋予 p 假名

$query = $repository->createQueryBuilder('p')

->where('p.price > :price')

->setParameter('price', '19.99')

->orderBy('p.price', 'ASC')

->getQuery();

$products = $query->getResult();

// to get just one result: / 要得到一个结果:

// $product = $query->setMaxResults(1)->getOneOrNullResult();

QueryBuilder对象包含了创建查询时的所有必要方法。通过调用getQuery()方法,query builder将返回一个标准的Query对象,可用于取得请求的结果集。

Query Builder更多信息,参考Doctrine的 Query Builder 文档。

把自定义查询组织到Repository类中 ¶

前面所有的查询是直接写在你的控制器中的。但对于程序的组织来说,Doctrine提供了一个专门的repository类,它允许你保存所有查询逻辑到一个中心位置。

配置 ¶

Doctrine是高度可配置的,虽然你可能永远不会去关心那些选项。要了解Doctrine的配置信息,参考 config reference。

Doctrine字段类型参考 ¶

Doctrine配备了大量可用的字段类型。每一个都能把PHP数据类型映射到特定的字段类型中,无论你使用什么数据库。对于每一个字段类型, Column 都可以被进一步配置,可以设置 length、nullable 行为,name 或者其他选项。可用字段类型的列表,参考 Mapping Types documentation。

Associations(关系) 和 Relations(关联) ¶

Doctrine 提供了你所需要的管理数据库关系(也被称为关联-associations)的所有的功能。更多信息,参考 如何使用Doctrine Associations / Relations。

总结 ¶

有了Doctrine,你可以集中精力到你的 对象 以及 如何把它应用到程序中,而数据库持久化则是第二位。这是因为Doctrine允许你使用任何的PHP对象来保存你的数据,并且依靠“元数据映射”信息来把一个对象的数据映射到一个特定的数据表之中。

Doctrine有很多强大的功能等着你去学习,像是relationships(关联),复杂查询和事件监听。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值