inlm / query-object
LeanMapper 的查询对象概念
Requires
- php: >=5.3.0
- tharos/leanmapper: >=2.3
Requires (Dev)
- nette/tester: ~1.2
README
警告! 此库已被 废弃,请使用 mibk/LeanMapperQuery 代替。它包含此库的所有更改以及更多功能。
Lean Mapper Query
Lean Mapper Query 是为 Lean Mapper 库 设计的 查询对象 概念,它通过自动连接(从 NotORM 库 中汲取灵感)帮助构建复杂的查询。查看 建议的基本类。对于捷克语文档,请参阅 wiki。
功能
- 它作为 SQL 预处理器运行,因此大多数 SQL 表达式都可用
- 使用点表示法(@book.tags.name)自动连接
- 能够查询仓库或实体
- 支持隐式过滤器
安装
它可以通过 Composer 安装。
composer require inlm/query-object
它做了什么?
假设我们有以下仓库
class BaseRepository extends LeanMapper\Repository { public function find(IQuery $query) { $this->createEntities($query ->applyQuery($this->createFluent(), $this->mapper) ->fetchAll() ); } } class BookRepository extends BaseRepository { }
以及以下实体
/** * @property int $id * @property string $name */ class Tag extends LeanMapper\Entity { } /** * @property int $id * @property Author $author m:hasOne * @property Tag[] $tags m:hasMany * @property DateTime $pubdate * @property string $name * @property bool $available */ class Book extends LeanMapper\Entity { } /** * @property int $id * @property string $name * @property Book[] $books m:belongsToMany */ class Author extends LeanMapper\Entity { }
我们构建一个 查询
$query = new Inlm\QueryObject\Query; $query->where('@author.name', 'Karel');
现在,如果我们想获取所有作者名为 Karel 的书籍,我们必须这样做
$bookRepository = new BookRepository(...); $books = $bookRepository->find($query);
数据库查询将如下所示
SELECT [book].* FROM [book] LEFT JOIN [author] ON [book].[author_id] = [author].[id] WHERE ([author].[name] = 'Karel')
您可以看到它通过点表示法执行自动连接。它支持 Lean Mapper 所知的所有类型的关系。
使用 SQL 函数非常简单。我们可以像这样更新查询
$query->where('DATE(@pubdate) > %d', '1998-01-01'); $books = $bookRepository->find($query);
并将数据库查询更改为以下内容
SELECT [book].* FROM [book] LEFT JOIN [author] ON [book].[author_id] = [author].[id] WHERE ([author].[name] = 'Karel') AND (DATE([book].[pubdate]) > '1998-01-01')
不要重复自己
您可以扩展 Query
并定义自己的方法。
class BookQuery extends Inlm\QueryObject\Query { public function restrictAvailable() { $this->where('@available', TRUE) ->orderBy('@author.name'); return $this; } } ///////// $query = new BookQuery; $query->restrictAvailable(); $books = $this->bookRepository->find($query);
查询实体
还可以查询实体属性(目前仅限于那些具有 BelongsToMany
或 HasMany
关系的属性)。让我们构建 BaseEntity
class BaseEntity extends Inlm\QueryObject\Entity { protected static $magicMethodsPrefixes = array('find'); protected function find($field, IQuery $query) { $entities = $this->queryProperty($field, $query); return $this->entityFactory->createCollection($entities); } } /* * ... */ class Book extends BaseEntity { }
请注意,BaseEntity
扩展了 Inlm\QueryObject\Entity
以使以下成为可能。
我们已将 find
方法定义为 protected
,因为在 $magicMethodsPrefixes
属性中指定方法名称后,您可以像这样查询实体
$book; // previously fetched instance of an entity from a repository $query = new LeanMapper\Query; $query->where('@name !=', 'ebook'); $tags = $book->findTags($query);
魔法方法 findTags
最终会调用您的受保护的 find
方法,并将 'tags' 作为第一个参数。
生成的数据库查询如下所示
SELECT [tag].* FROM [tag] WHERE [tag].[id] IN (1, 2) AND ([tag].[name] != 'ebook')
where 子句中的第一个条件 [tag].[id] IN (1, 2)
来自实体遍历(标签针对特定书籍实体的自身标签进行查询)。
您还可以做什么?
如果我们稍微修改我们的 BaseRepository
和 BaseEntity
,我们可以简化与查询对象的协作。请查看 建议的基本类 以实现这一点。它使以下成为可能。
$books = $bookRepository->query() ->where('@author.name', 'Karel') ->where('DATE(@pubdate) > ?', '1998-01-01') ->find(); // or... $tags = $book->queryTags() ->where('@name !=', 'ebook') ->find();
许可证
版权(c)2013 米哈尔·博胡斯拉维克
在MIT许可证下授权。