mbohuslavek/leanmapper-query

LeanMapper的查询对象概念

v1.3.0 2022-07-20 10:03 UTC

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);

查询实体

还可以查询实体属性(目前仅支持具有 BelongsToManyHasMany 关系的属性)。让我们修改 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) 来自实体遍历(标签针对特定书籍实体的自身标签进行查询)。

您还能做什么?

如果我们稍微修改 BaseRepositoryBaseEntity,我们可以简化查询对象的工作。请查看 建议的基本类。这使得以下内容成为可能。

$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 许可证下授权。