doctrine 是什么?
PHP
开发者都知道PHP
如果想要连接到数据库,需要使用到 PDO
扩展,PDO
的意义在于它提供了一个面向数据库连接的抽象层,你可以使用相同的函数来连接到不同的数据库。但是 PDO
只是提供了基本的增删改查方法,对于 web 开发来说效率比较低,开发过程繁琐。于是很多第三方框架在 PDO
之上进行了再次封装,这类框架通常被称为 ORM
框架,也即对象关系映射。一般每个 web
框架都会封装自己的 ORM
框架,比如 Laravel
中有 Eloquent
,ThinkPHP
也自己封装了一套。而doctrine
也是一个用PHP
编写的 ORM
框架,Symfony
框架就直接整合了改组件作为内置的 ORM
框架。
doctrine 有哪些特点?
面向实体(Entry
)而不是数据表
在进行数据映射时,大多数ORM
框架采取的都是数据表-Model类
一一对应连接,采取的是Active Record
模式,核心思想是“面向数据表”,其增删改查是面向数据表的,而 Doctrine
采取的是data mapping
模式,核心思想是“面向实体),在数据表的基础之上抽象成实体,是面向实体的增删改查,这里说的实体概念是领域驱动设计中的实体,在这里不详细讨论。
使用DQL
查询
由于 Dcotrine
提供的是面向实体的查询,因此它提供了一个类似SQL
语法的操作,称之为DQL
(Doctrine
查询语言)。这让我们可以将数据库的数据作为PHP
的对象进行操作,而不用关心数据库的细节。这也使得我们可以方便的切换数据库后端引擎。
安装和配置Doctrine
安装
可以使用 Composer
来安装 doctrine
,在你的composer.json
文件中添加如下
1 | { |
使用composer install
命令来下载安装。
如果你使用的是 Symfony
框架,由于 Symfony
内置 doctrine
,无需进行额外的安装步骤。
配置(Symfony
中)
主要配置数据库连接信息,这部分信息通常配置在 app/config/parameters.yml
1 | # app/config/parameters.yml |
通常在参数文件parameters.yml
来定义配置。
app/config/config.yml
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
配置之后,Doctrine
就可以连接到数据库了。
Doctrine
使用步骤
1. 定义一个实体(Entry
) 类
比如我们需要一个Product
类,以及它包含三个属性。
1 |
|
2. 添加映射关系
与其他 ORM
框架不同的是,由于 Doctrine
在实现层面使用的是Data mapping
的模式,因此需要一个映射文件,结构如下:
Doctrine
的Mapper
文件可以采用三种格式,分别是注解方式,yaml
格式,和 xml
格式,后面我们使用 xml
格式:
1 | <!-- src/AppBundle/Resources/config/doctrine/Product.orm.xml --> |
以上定义了一个entry
,包含了一个id
字段和三个其他字段。
除此之外,doctrine
提供了一个命令来验证映射是否正确:
1 | $ php bin/console doctrine:schema:validate |
注意事项:
- 格式不能混用,单个实体只能使用单个格式来定义,不能混用。
- 数据表表明最好不要使用 SQL关键字,比如
group
,user
等,因为在数据库引擎中可能导致SQL
错误。
3. 使用实体管理器
doctrine
使用EntityManager
来统一对数据库进行访问
新增
1 | $product = new Product(); |
查找
1 | $product = $this->getDoctrine() |
更新
1 | $em = $this->getDoctrine()->getManager(); |
删除
1 | $em->remove($product); |
通过以上实例可以看出,Doctrine
通过entityManager
管理着Entity
,所有的查询,更新操作都是通过entityManager
完成的,通过entityManager
我们获取到某一特定Entity
的Repository
,通过Repository
提供的各种finders
来查询Entity
。
配置关联关系
主要是在mapper
文件中配置实体和子实体,值对象的关联关系。
多对一关系
比如多个评论对应同一篇文章:
1 | <doctrine-mapping> |
一对一关系
比如产品与物流:
1 |
|
一对多关系
比如一个产品有多个 feature
1 | <entity name="Product"> |
使用查询对象
Criteria
是一个类似于 Laravel
中的query
,使用Criteria
可以构建多个查询条件。
$criteria = Criteria::create();
$expr = Criteria::expr(); //表达式对象
$criteria->andWhere($expr->eq('id', 3)) //添加 id=3的条件
//获取查询结果
$results = $this->xxxRepository
->matching($criteria)
->getValues();