etten/doctrine

Nette 框架的 Doctrine 辅助工具和扩展

维护者

详细信息

gitlab.com/etten/doctrine

源代码

问题

安装: 7,729

依赖项: 1

建议者: 0

安全: 0

星级: 0

分支: 0

v4.7.2 2017-03-31 16:45 UTC

README

提供一些辅助工具和扩展,将 Doctrine 2 ORM 集成到 Nette 框架中。

安装

首先使用 Composer 安装包

$ composer require etten/doctrine

然后在 config.neon 中注册基本的 DI 扩展

extensions:
	etten.doctrine: Etten\Doctrine\DI\DIExtension

EntityManager 面向对象

Doctrine 的默认 EntityManager 是一个神级类。怪物。它做得太多,违反了 SRP,mock 很难,...

但你可以使用

  • Etten\Doctrine\Facade(抽象类)
  • Etten\Doctrine\Persister
  • Etten\Doctrine\RepositoryLocator
  • Etten\Doctrine\Transaction

服务会自动使用 Etten\Doctrine\DI\DIExtension 注册。

辅助工具

集合

当你有例如 Product:Tags (M:N) 关联,并通过设置器 Product::setTags 设置所有值时,你可能会得到一个 Duplicate entry... 错误。因为你在设置新的关联(替换 Product 的 Tags 集合实例)。

但这类操作可以使用 Etten\Doctrine\Helpers\Collections 非常容易完成。

只需使用


	public function setTags(array $tags):Product
	{
		\Etten\Doctrine\Helpers\Collections::replace($this->tags, $tags);
		return $this;
	}

保留 $this->tags 实例,只添加新项目,从集合中删除已删除的项目。

FieldOrderHelper

有时,你需要根据另一个数组中给出的顺序排序项。

在 MySQL 中,你可以使用 ORDER BY FIELD

但当我们使用 Doctrine 时,我们的代码应该是平台无关的,我们不应该直接使用 DBMS 特定的函数。

你可以通过 Etten\Doctrine\Helpers\FieldOrderHelper 在 PHP 中对项目进行排序。请参阅 实现

注意:此类操作在 PHP 中效率低下。仅用于少量过滤项。 如果你有数百项,最好重写代码并在 DBMS 中直接排序项目,而不是在 PHP 中。

随机化器

随机化器帮助你找到看起来随机的结果,而无需使用 ORDER BY RAND() 子句。

它计算给定 Query 对象中的所有项,并选择随机偏移量。

然后应用限制并返回一个随机打乱顺序的数组结果。

为了获得更好的结果,偏移量 + 限制在多次迭代中执行(默认为每次 25 项)。 这会增加操作的成本,但结果不是按插入顺序排序。

扩展

缓存

Etten/Doctrine 提供了一种方便的缓存失效机制,当特定实体发生变化时(在 Doctrine 术语中:持久化、更新、删除)。

实体必须实现 Etten\Doctrine\Entities\Cacheable,请参阅 接口

Cacheable 的基本实现可以在 Etten\Doctrine\Entities\Attributes\Cache 中获得,请参阅 特性

你还可以从 Etten\Doctrine\Entities\Entity实现)继承,你将获得这两个要求。

最后,你必须注册一个 Nette DI 扩展

# app/config.neon

extensions:
	etten.doctrine.cache: Etten\Doctrine\DI\CacheExtension

当扩展注册时,缓存会自动失效。如何实现?这取决于具体实现。默认情况下,请参阅Etten\Doctrine\Entities\Attributes\CacheEtten\Doctrine\Caching\NetteCacheInvalidator

UUID

如果您需要在持久化和刷新之前获取项目ID,可以使用UUID作为主索引。

Doctrine 2原生支持UUID(GUID),但这是由RDMS自动生成的值。在持久化和刷新之前,我们不知道ID。

但在PHP中,您可以在持久化和刷新之前生成UUID。

有关更多信息,请参阅ramsey/uuid-doctrinePercona博客

在etten/doctrine中,UUID类型的使用方式略有不同

  • UuidBinary实际上是一个二进制属性(PHP字符串,SQL二进制),而不是Uuid实例。但您可以在需要时获取十六进制值(例如,在表单中选择)。如果您需要手动在原始SQL中插入UUID,请使用类似UNHEX(REPLACE(UUID(), '-', ''))的语句。
  • Uuid实际上是一个字符串属性(PHP + SQL),而不是Uuid实例。请参阅UuidBinary。
  • UuidBinary默认使用InnoDB优化变体。
  • 当您需要进行类型简单转换时,可以使用UuidConverter

在Nette框架应用程序中,通过注册扩展简单添加UUID支持

# app/config.neon

extensions:
	etten.doctrine.uuid: Etten\Doctrine\DI\UuidExtension

InstanceId

如果您需要在持久化和刷新之前获取项目ID,可以使用InstanceId作为主索引。

这是一个由PHP生成的全局唯一整数,而不是RDMS。

您可以通过注册Nette DI扩展来添加InstanceId支持

# app/config.neon

extensions:
	etten.doctrine.instanceId: Etten\Doctrine\DI\InstanceIdExtension

etten.doctrine.instanceId:
	path: safe://%storageDir%/instance-generator.id

DQL

MySQL MATCH AGAINST

代码的原始来源在这里:这里

在配置中注册DQL

# app/config.neon

kdyby.doctrine:
	dql:
		string:
			MATCH: Etten\Doctrine\DQL\MatchAgainstFunction

用法

<?php

public function search(string $q)
{
	$qb = $this->createQueryBuilder()
		->addSelect('MATCH (a.title) AGAINST (:search) as HIDDEN score')
		->addWhere('MATCH (a.title) AGAINST (:search) > 1')
		->setParameter('search', $q)
		->orderBy('score', 'desc');

	return new Paginator($qb);
}

MySQL FIELD

代码的原始来源在这里:这里

在配置中注册DQL

# app/config.neon

kdyby.doctrine:
	dql:
		string:
			MATCH: Etten\Doctrine\DQL\FieldFunction

用法

<?php

public function search(array $ids)
{
	$qb = $this->createQueryBuilder()
		->addSelect('FIELD(p.id, :ids) as HIDDEN score')
		->andWhere('p.id IN :ids')
		->setParameter('ids', $ids)
		->orderBy('score', 'desc');

	return new Paginator($qb);
}

其他(不包括在此包中)

有关更多功能,请访问beberlei/DoctrineExtensions