mbohuslavek / leanmapper-query
LeanMapper的查询对象概念
Requires
- php: ^7.4 || ^8.0
- tharos/leanmapper: >=3.0
Requires (Dev)
- nette/tester: ~2.3.4
- phpstan/phpstan: ~1.8
This package is auto-updated.
Last update: 2024-09-20 17:10:34 UTC
README
Lean Mapper Query 是 Lean Mapper 库的查询对象概念,通过自动连接(从 NotORM 库 中汲取灵感)帮助构建复杂的查询。查看 建议的基本类。对于捷克语文档,请参阅 wiki。
功能
- 行为类似于
SQL
预处理器,因此大多数 SQL 表达式都是可用的 - 使用点表示法自动连接
- 能够查询存储库或实体
- 支持隐式过滤器
安装
它可以通过 Composer 安装。
composer require mbohuslavek/leanmapper-query
它做什么?
假设我们有以下存储库
class BaseRepository extends LeanMapper\Repository { public function find(Query $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 LeanMapperQuery\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 LeanMapperQuery\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 LeanMapperQuery\Entity { protected static $magicMethodsPrefixes = ['find']; protected function find($field, Query $query) { $entities = $this->queryProperty($field, $query); return $this->entityFactory->createCollection($entities); } } /* * ... */ class Book extends BaseEntity { }
请注意,BaseEntity
必须扩展 LeanMapperQuery\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 Michal Bohuslávek
在 MIT 许可证下授权。