inlm/query-object

该软件包已被废弃,不再维护。未建议替代软件包。

LeanMapper 的查询对象概念

v2.0.1 2018-07-18 20:24 UTC

This package is auto-updated.

Last update: 2021-11-14 01:04:47 UTC


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

查询实体

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

您还可以做什么?

如果我们稍微修改我们的 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 米哈尔·博胡斯拉维克

在MIT许可证下授权。