huttopia / doctrine
为doctrine添加一些特性并修复bug,而不需要创建分支
Requires
- php: >=7.1.3
- doctrine/doctrine-bundle: ^1.6
- doctrine/doctrine-cache-bundle: ^1.3
- doctrine/orm: 2.5.6
- steevanb/composer-overload-class: ^1.3
- steevanb/doctrine-entity-merger: ^1.0
- steevanb/doctrine-events: ^1.2
- steevanb/doctrine-read-only-hydrator: ^2.2
Requires (Dev)
- steevanb/doctrine-stats: ^1.0
This package is auto-updated.
Last update: 2024-09-07 21:16:04 UTC
README
huttopia/doctrine
Doctrine是一个非常优秀的ORM,功能齐全,我们非常喜欢它!
但是,说实话,自2015年4月2日以来没有发布过任何主要版本(2.6已经发布,但现在bug太多),一些bug还没有修复,当你提交一个修复bug的PR时,创建补丁版本需要花费太多的时间。
因此,我们决定创建
我们决定不创建Doctrine的分支,因为我们想跟随Doctrine的发布。现在创建分支可能很好,但两年后...
当我们需要覆盖一个类时,我们使用steevanb/composer-overload-class。当你需要这样做时,这是一个好方法,而不需要在所有地方重命名命名空间(我们不能,这不是一个分支;))。
安装
将其添加到您的composer.json文件中
composer require huttopia/doctrine ^1.3.2
注册HuttopiaDoctrineBundle
# app/AppKernel.php class AppKernel extends Kernel { public function registerBundles(): array { $bundles = [ new Huttopia\Doctrine\Bridge\Symfony3\HuttopiaDoctrineBundle() ]; return $bundles; } }
更改Doctrine配置
# app/config/config.yml doctrine: orm: repository_factory: huttopia.doctrine.repository_factory default_repository_class: Huttopia\Doctrine\Orm\EntityRepository
配置
# app/config/config.yml huttopia_doctrine: repository_factory_service: huttopia.doctrine.repository_factory # this is default value
Doctrine bugs
由于某些原因,Doctrine未修复或未修复的bug
- fixed by steevanb/doctrine-events 使用extraUpdates修复Doctrine UnitOfwork的bug,这些更新在调用flush()之前添加和删除实体时不会被删除
- #6042(未修复) getId()懒加载实体,如果getId()在trait中:未修复,只是为了提醒为什么我们不用trait来实现getId()
- #6110(已修复) 清除 $this->collection 即使它为空,以重置键值
- #6509(在此修复) PersistentCollection::clear() 和 removeElement() 与 orphanRemoval 一起会删除你的实体,即使你不想这样做
目前,我们修复了doctrine/orm依赖项的2.5.6版本:>2.5.6,2.6的标签错误(一些依赖项位于dev-master,没有版本),一些BC等。
当2.6版本经过更多测试时,我们将更改它。
作为服务存储库
是的,你也需要它;)存储库作为服务是最大的改进之一。
现在,我们可以使用huttopia.repository标签将您的存储库定义为服务
services: bar_repository: class: Foo\Repository\BarRepository arguments: ['@service', '%parameter%'] tags: - { name: huttopia.repository, entity: Foo\Bar }
您需要在您的存储库中将 extends Doctrine\ORM\EntityRepository 改为 extends Huttopia\Doctrine\Orm\EntityRepository
请注意,我们的存储库移除了魔术方法(例如findOneById())。
但它添加了许多方法
- getClassName(): string
- getClassTableName(): string
- createQueryBuilderWithoutSelect(string $alias, string $indexBy = null): QueryBuilder
- get(int $id): Entity
- getOneBy(array $criteria, array $orderBy = null): Entity
- countAll(): int
- countBy(array $params): int
- findReadOnlyBy(array $criteria, array $fields = null, array $orderBy = null, $limit = null, $offset = null): array
- getPartialReference(int $id)
find()和get(),以及findOneBy()和getOneBy()之间的区别:当实体不存在时,find()将返回null,而get()将抛出异常。
当您使用PARTIAL时,您可以使用createQueryBuilderWithoutSelect()而不是createQueryBuilder(),后者不会选择所有根实体字段。
删除单表继承中的无用的discriminator
对于SINGLE_TABLE_INHERITANCE实体,Doctrine会在所有SQL查询中添加discriminator列。
但是,如果您想查询所有实体,Doctrine 会添加不必要的 WHERE 子句,带有鉴别器:这并不利于性能;)
Huttopia\Doctrine\SqlWalker\IgnoreDiscriminator 修改了 Doctrine SqlWalker,仅在需要时添加 WHERE 子句。
为单个查询添加它
use Huttopia\Doctrine\SqlWalker\IgnoreDiscriminator $queryBuilder ->getQuery() ->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, IgnoreDiscriminator::class);
为所有查询添加它
# app/AppKernel.php class AppKernel { public function boot(): void { parent::boot(); foreach ($this->getContainer()->get('doctrine')->getManagers() as $manager) { if ($manager instanceof EntityManagerInterface) { $manager->getConfiguration()->setDefaultQueryHint( Query::HINT_CUSTOM_OUTPUT_WALKER, IgnoreDiscriminator::class ); } } } }
#6509 修复 PersistentCollection 的 orphanRemoval 管理
当您在 PersistentCollection 上调用 remove()、removeElement() 或 clear(),并且您的 manyToOne 配置将 orphanRemoval 设置为 true 时,PersistentCollection 将将您删除的实体添加到 UnitOfWork::$orphanRemovals 中。
flush() 将读取 UnitOfWork::$orphanRemovals,并删除所有实体,尽管它们被删除后又被添加。
因此,如果您删除一个实体,然后再次添加它,然后 flush(),最终,您的实体将被删除。
为了修复它,我们覆盖了 PersistentCollection,并在将实体添加到 PersistentCollection 时取消孤儿删除的调度。
覆盖 PersistentCollection 来修复它
{ "extra": { "composer-overload-class": { "Doctrine\\ORM\\PersistentCollection": { "original-file": "vendor/doctrine/orm/lib/Doctrine/ORM/PersistentCollection.php", "overload-file": "vendor/huttopia/doctrine/ComposerOverloadClass/Orm/PersistentCollection.php", "replace": true } } } }
启用 steevanb/doctrine-events
它将替换 EntityManager,以添加一些事件:onCreateEntityOverrideLocalValues、onCreateEntityDefineFieldValues、onNewEntityInstance 等。
请参阅 安装 以进行安装。
启用 steevanb/doctrine-entity-merger
当您在 DQL 中使用 PARTIAL 时,您只检索所需的字段,而不是所有实体字段。
但是,如果您对同一实体执行 2 个 PARTIAL,但字段不同,最终实体将不会包含第二个 PARTIAL 的数据,只有第一个被填充。
请参阅 安装 以进行安装。
启用 steevanb/doctrine-read-only-hydrator
请参阅 基准测试,您将了解为什么我们使用 ReadOnlyHydrator;)
请参阅 安装 以进行安装。
启用 steevanb/doctrine-stats
steevanb/doctrine-stats 添加了大量关于查询、填充时间、延迟加载实体等的统计信息。
请参阅 安装 以进行安装。