solirismedia / yetorm
基于 Nette\Database 的轻量级 ORM
Requires
- php: >=5.6.0
- nette/database: ^2.4
- nette/reflection: ^2.3
- nette/utils: ^2.4
Requires (Dev)
- nette/caching: ^2.5
- nette/robot-loader: ^2.4
- nette/tester: ^2.0
- tracy/tracy: ^2.4
This package is auto-updated.
Last update: 2024-09-06 16:52:59 UTC
README
基于 Nette\Database 的轻量级 ORM
快速入门
考虑以下数据库模式
实体
首先,我们将根据上述模式创建实体类。定义实体属性有两种方式 - 通过 @property[-read]
注解,或者简单通过 getter 和 setter。
标签
/** * @property-read int $id * @property string $name */ class Tag extends YetORM\Entity {}
作者
/** * @property-read int $id * @property string $name * @property string $web * @property \DateTime $born */ class Author extends YetORM\Entity {}
书籍
在 Book
实体中存在一些关系 - 两个 N:1 的 Author
和 M:N 的 Tag
关系。每个 YetORM\Entity
中都有一个 YetORM\Record
实例,它是一个简单的 Nette\Database\Table\ActiveRow
包装器。这意味着我们可以通过它访问相关记录或列值。
/** * @property-read int $id * @property string $title * @property string $web * @property string $slogan */ class Book extends YetORM\Entity { function getAuthor() { return new Author($this->record->ref('author', 'author_id')); } function getMaintainer() { return new Author($this->record->ref('author', 'maintainer_id')); } function getTags() { $selection = $this->record->related('book_tag'); return new YetORM\EntityCollection($selection, 'Tag', 'tag'); } }
使用 $record->ref($table, $column)
我们可以通过列 $column
访问表 $table
中的相关行 - 非常简单。
M:N 关系是通过 YetORM\EntityCollection
实例实现的 - 这是一个实体惰性集合。在这种情况下,它遍历来自 book_tag
表的所有相关行(第一个参数),创建 Tag
(第二个参数)的实例,并在每个相关的 book_tag
表行中访问相关的 tag
表行(第三个参数),然后将其传递给 Tag
实体构造函数 :-)
这听起来很疯狂,但实际上很容易习惯。
有了这些知识,我们现在可以简单地为 Author
实体添加一些有用的方法
// class Author function getBooksWritten() { $selection = $this->record->related('book', 'author_id'); return new YetORM\EntityCollection($selection, 'Book'); } function getBooksMaintained() { $selection = $this->record->related('book', 'maintainer_id'); return new YetORM\EntityCollection($selection, 'Book'); }
仓库
每个仓库都必须定义表和实体类名称 - 通过 @table
和 @entity
注解,或者通过受保护的 $table
和 $entity
类属性。
/** * @table book * @entity Book */ class BookRepository extends YetORM\Repository {}
获取集合
YetORM\Repository
提供了基本的 findAll()
和 findBy($criteria)
方法,两者都返回已提到的 EntityCollection
。
我们可以简单地遍历所有书籍
$books = new BookRepository($connection); // $connection instanceof Nette\Database\Context foreach ($books->findAll() as $book) { // $book instanceof Book echo $book->title; echo $book->getAuthor()->name; foreach ($book->getTags() as $tag) { // $tag instanceof Tag echo $tag->name; } }
获取单个实体
$book = $books->getByID(123); // instanceof Book or NULL if not found
魔法 findBy<Property>()
和 getBy<Property>()
方法
我们不需要手动编写 findByTitle($title)
方法,如下所示
function findByTitle($title) { return $this->findBy(array( 'title' => $title, )); }
我们可以直接调用
$books->findByTitle($title); // without having the method implemented
这将返回具有该确切标题的书籍集合。
要获取单个实体,请使用魔法 getBy<Property>($value)
方法
$book = $books->getByIsbn('<isbn_code>'); // instanceof Book or NULL if not found
为了与 IDE 代码补全一起使用这些魔法方法,我们可以使用 @method
注解
/** * @table book * @entity Book * @method YetORM\EntityCollection|Book[] findByTitle(string $title) * @method Book|NULL getByIsbn(string $isbn) */ class BookRepository extends YetORM\Repository {} /** * @property-read int $id * @property string $title * @property string $isbn */ class Book extends Entity {}
重要:使用魔法
findBy<Property>()
和getBy<Property>()
方法时,请确保您已经通过@property
注解定义了该属性!
注意:魔法
findBy<Property>()
和getBy<Property>()
无法在类型为 Entity 的关系属性上使用。
持久化
要持久化更改,我们只需调用 $repository->persist($entity)
。
$book->web = 'http://example.com'; $books->persist($book);
就是这样!
附加说明
- 无标识映射
- 查询效率 - 集合(或
YetORM\Record
)使用Nette\Database
的效率 - 集合操作 - 集合可以通过
$coll->orderBy($column, $dir)
排序,并通过$coll->limit($limit, $offset)
限制
更多
有关更多示例,请参阅 测试。