在新的标准版本的Symfony框架中已经集成了Doctrine,Doctrine就是一种对象关系映射(ORM)同时也是一种数据库抽象层(DBAL),使用ORM和DBAL能让我们很轻易的操作数据库。本文章重点在于在Symfony中使用Doctrine——如何创建数据库表的模型,如何创建表的关系,怎么查询数据等等。
创建和配置数据库
Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: utf8mb4
collate: utf8mb4_unicode_ci
Doctrine作为PDO的顶层可以操作任何支持PDO的数据库操作系统(比如MySQL,PostgreSQL,Microsoft SQL,MongoDB和MariaDB)。这里推荐设置默认的数据库字符集和排序集为utf8mb4。有别于老的utf8字符集,utf8mb4支持4字节的Unicode编码。数据库的主机地址、端口、数据库名称、用户名和密码通常在composer安装的时候已经设置好,但是你仍然可以在app/config/parameters.yml中编辑。
创建实体类
每一个实体(数据表)应表示为一个类,并且文件放置在AppBundle/Entity目录下:
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class User
{
private $id;
private $name;
private $email;
private $password;
private $createdAt;
}
这个类表示了用户数据表,它拥有id,name,email,password和created_at字段。为了给Doctrine提供每一个字段的类型和关系,我们还要写一些注释:
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $email;
/**
* @var string
*/
private $password;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity="Group", inversedBy="users")
* @ORM\JoinColumn(name="group_id", referencedColumnName="id")
*/
private $group;
}
表名的注释是可选的,如果你省略了,Doctrine会根据类的名称去自动生成一个对应的表名。在上面的代码中,只展示了一些字段的属性。
现在让我们来创建一个表用来描述用户组,每一个用户只能在其中一个用户组中:
// src/AppBundle/Entity/Group.php
/**
* @ORM\Entity
* @ORM\Table(name="group")
*/
class Group
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @ORM\Column(nullable=true)
* @ORM\Column(type="text")
*/
private $description;
/**
* @ORM\OneToMany(targetEntity="User", mappedBy="group")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
}
请注意,表关系同样被写在了注释当中。OneToMany是一个关系的名称,targetEntity是一个实体类,JoinColumn定义了外键。同时,在OneToMany的关系中,我们需要在构造方法中声明一个变量ArrayCollection。
类中的变量被定义为了私有变量,为了获取到这些私有变量,我们需要创建一个设置变量和获取变量的方法。你可以手动创建这些方法,但是在你的项目目录中使用下面的命令可以轻松的实现:
php app/console doctrine:generate:entities AppBundle/Entity/User
在执行了上面的命令之后,User类会变成下面的样子:
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $email;
/**
* @var string
*/
private $password;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity="Group", inversedBy="users")
* @ORM\JoinColumn(name="group_id", referencedColumnName="id")
*/
private $group;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* @param mixed $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return mixed
*/
public function getPassword()
{
return $this->password;
}
/**
* @param mixed $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* @return mixed
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* @param mixed $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
}
}
创建和更新数据库模式
在Doctrine中,在已经有了一个实体咧的基础上执行下面的命令可以轻易的创建一个数据库模式:
php app/console doctrine:schema:update --force
上面的命令不仅可以创建数据库模式,同时在你的开发过程中还会更新数据库模式。在数据库中执行SQL查询的时候,不推荐使用数据库模式,推荐在生产环境中更新。
数据库查询
到这一步,我们已经创建了一个实体类,定义了它的表关系并且创建了数据库模式。现在我们将要学习如何在数据库中创建、查询、更新和删除数据。
$group = new Group();
$group->setName('Administrator');
$group->setDescription('Users with highest privileges in the system');
$em = $this->getDoctrine()->getManager();
// Tells Doctrine you want to save the group (no queries yet)
$em->persist($group);
// This line actually executes the SQL query
$em->flush();
在刚刚创建的用户组表中查询id:
$group->getId();
从数据库中查询数据:
$group = $this->getDoctrine()
->getRepository('AppBundle:Group)
->find($groupId);
更新数据:
// Fetch the group
$em = $this->getDoctrine()->getManager();
$group = $em->getRepository('AppBundle:Group)->find($groupId);
// If the group does not exist, throw an exception
if (!$group) {
throw $this->createNotFoundException(
'Group not found'
);
}
// Update data
$group>setDescription('New group description.');
$em->flush();
从数据库中删除数据:
// Fetch group
$em = $this->getDoctrine()->getManager();
$group = $em->getRepository('AppBundle:Group)->find($groupId);
// Remove group
$em->remove($group);
$em->flush();