MercuryORM - 简单实体框架






3.77/5 (6投票s)
一个轻量级的基于实体的框架
Using the Code
我们从介绍 Mercury
\DbContext
类开始。 DbContext
类是一个 abstract
类,不能直接实例化,必须被继承。必须创建一个具体的类来继承 DbContext
。通过继承 DbContext
,您实际上是为数据库相关任务创建了一个包装器。 DbContext
类公开了一个 dbSet()
方法,该方法用于注册实体。下面的清单 1.1 展示了一个带有两个已注册实体的示例 BlogContext
类。
列表 1.1
class BlogContext extends \Mercury\DbContext{
public function getUsers(){
return $this->dbSet('Models\User');
}
public function getPosts(){
return $this->dbSet('Models\Post');
}
}
上面的上下文 (BlogContext
) 定义了两个方法 (getUsers()
和 getPosts()
),这两个方法都将返回 Mercury
\DbSet
的一个实例,但是每个 DbSet
将维护其实体的数据。在上面的示例中, getUsers()
方法注册了一个 DbSet
,它将负责管理 Models\User
实体。 DbSet
实例由 DbContext
在内部以数组的形式管理。如果随后调用 getUsers()
方法,则会返回先前实例化的 DbSet
。 在我们继续之前,让我们看看如何使用新创建的 BlogContext
连接到数据库。下面的清单 1.2 展示了如何使用默认设置和连接字符串连接到 MySQL 数据库。
列表 1.2
// Default settings
$blogContext = new BlogContext();
// Using a connection string
$blogContext = new BlogContext('driver=mysql;host=127.0.0.1;
dbname=blogcontext;uid=root;pwd=pass;charset=utf8');
使用默认设置实例化上下文时,上下文的名称用作数据库名称,并且使用用户名 "root
" 和空密码在 localhost 上建立连接。
DbSet
如前所述,每个 DbSet
实例管理它所注册类型的实体集合。除了管理实体集合之外, DbSet
还维护实体元数据。 实体元数据是描述实体的数据,并使用注释放置在实体类中。 下面的清单 1.3 展示了一个带有元数据的 Model\User
实体。
清单 1.3
namespace Models;
//[TableName("users")]
//[UniqueKey("user_id")]
class User {
protected $user_id;
//[Required]
//[StringLength(30)]
protected $first_name;
//[Required]
//[StringLength(30)]
protected $last_name;
//[Required]
//[StringLength(50)]
//[DefaultValue("user@mail.com")]
protected $email;
public function setFirstName($name){
$this->first_name = $name;
}
public function setLastName($name){
$this->last_name= $name;
}
public function setEmail($email){
$this->email = $email;
}
}
上面的代码示例使用注释来为实体和实体属性分配属性。 每个属性都是一种特定类型。 例如, Required
属性的类型为 Mercury\Attributes\Required
,而属性 StringLength
的类型为 Mercury\Attributes\StringLength
。 属性有助于强制执行验证并提供有关实体的元数据。 也可以使用 DefaultValue
属性为实体属性提供默认数据。
必须使用 DbSets add()
方法将实体的实例添加到其相关的 DbSet
中。 add
方法不会将实体持久化到数据库中,而是将实体的状态更改为 PERSIST
,这意味着当调用 DbContext
的 saveChanges()
方法时,该实体将被持久化到基础数据库。 一旦持久化, DbContext
将在内部集合中维护该实体,并将其状态更改为 PERSISTED
。 将实体添加到不相关的 DbSet
将引发 EntityException
类型的异常。 下面的清单 1.4 展示了如何创建一个新用户并将该用户持久化到数据库中。
清单 1.4
$user = new Models\User();
$user->setFirstName('John');
$user->setLastName('Smith');
$user->setEmail('j.smith@mail.com');
$blogContext = new BlogContext();
$blogContext->getUsers()->add($user);
$blogContext->saveChanges();
可以使用 add
方法将多个用户添加到 DbSet
,然后使用 saveChanges()
方法进行持久化。 saveChanges()
方法也用于更新记录。 在下一个示例中, DbSet
类的 find()
方法用于查找具有给定 user_id
的用户,然后更新用户详细信息,并使用 saveChanges()
方法更新用户详细信息。
清单 1.5
$blogContext = new BlogContext();
// Find a user with the user_id=3
$user = $blogContext->getUsers()->find(3);
// Change the email address
$user->setEmail('new@mail.com');
// Save changes
$blogContext->saveChanges();
上面的代码示例引入了一个 find()
方法。 find
方法用于在基础数据库中搜索记录,并将记录映射到 DbSet
实体类型。 由于 find 方法属于 DbSet
类,因此它知道表名和主键,因为 DbSet
维护实体元数据。 找到记录后,它将传递给 DbContext
,后者将其存储在内部集合中,并将实体的状态更改为 PERSISTED
,然后返回它。 还存在一个 findAll()
方法,该方法返回给定实体类型的数组。 findAll()
方法接受一个键/值数组,用作搜索条件。
也可以实现简单的关联。 在某些情况下,您可能有一个 insert
依赖于另一个 insert
。 考虑以下示例,您要创建一个也发表了一篇文章的用户。 用户和文章都将被持久化。 通常,您将持久化用户并返回用户的最后一个插入 id,用作文章的 author_id
的外键值。 下面的清单 1.6 展示了关联如何帮助插入用户和文章,而无需自己返回最后一个插入 id。
清单 1.6
$user = new Models\User();
$user->setFirstName('John');
$user->setLastName('Smith');
$user->setEmail('j.smith@mail.com');
$post = new Models\Post();
$post->setTitle('My first post');
$post->setBody('This is my first blog post');
$post->setAuthor($user);
$blogContext = new BlogContext();
$blogContext->getUsers()->add($user);
$blogContext->getPosts()->add($post);
$blogContext->saveChanges();
请注意, Models\Post
实体的 setAuthor()
方法如何接受 Models\User
实体对象。 当 Models\Post
实体被持久化时, DbContext
将查找 Models\User
实体并返回最后一个插入 id。
这标志着本文的结束。 请随时留下您的评论和建议。
历史
- 2014 年 6 月 29 日:初始版本