steevanb/doctrine-read-only-hydrator

仅用于读取的快速数据填充

2.3.0 2021-03-28 18:10 UTC

This package is auto-updated.

Last update: 2024-09-20 18:03:16 UTC


README

version doctrine php Lines Total Downloads Scrutinizer

doctrine-read-only-hydrator

当你使用 Doctrine 检索数据时,你可以得到一个包含值的数组,或者一个完全填充的对象。

数据填充是一个非常缓慢的过程,它会在多个填充具有相同实体时返回相同的实体实例。当你想要插入/更新/删除实体时,这是可以的。但当你只想检索数据而不编辑它(例如显示列表)时,它会非常慢。

如果你想真正从数据库中检索数据,而不获取 UnitOfWork 引用:使用 Doctrine 数据填充你无法做到。每次查询都不会使用查询结果中的数据填充一个新的实体,而是返回由 UnitOfWork 知道的第一个填充的实体。

所以,如果你不需要修改你的实体,你想要真正更快,或者只是检索数据库中存储的数据,你可以使用 SimpleObjectHydrator 或 ReadOnlyHydrator。

这些填充的实体不能被持久化/刷新,因为它们没有在 UnitOfwork 中注册以提高性能。

不会进行延迟加载:为了更快,并且因为大多数时候,你必须创建一个完整的 QueryBuilder,它返回你所需的所有内容。

变更日志

基准测试

此表显示了简单的基准测试结果(时间和 memory_get_peak_usage()),从 MySQL 5.7 数据库中检索了 30、1000 和 5000 个实体,使用 PHP 5.6.23 和 Doctrine 2.5.4。

当调用 $query->getArrayResult() 时使用 ArrayHydrator,当调用 $query->getResult()、$repository->findAll() 或 $repository->findBy() 时使用 ObjectHydrator。

SimpleObjectHydrator 和 ReadOnlyHydrator 由本库提供,请参阅上面的示例。

benchmark

正如预期的那样,getArrayResult() 是检索数据最快的方式。但是,你必须与数组一起工作,因此你不能使用实体方法。

ReadOnlyHydrator 比 Doctrine ObjectHydrator 快 4 倍,但比 ArrayHydrator(难以使用)慢 40%。

如果你想要尽可能快,但又想得到实体结果而不是数组,SimpleObjectHydrator 看起来相当不错。

SimpleObjectHydrator

使用 QueryBuilder 中选择的所有字段填充你的实体。如果你尝试访问未加载的属性,不会抛出异常,你可以调用所有访问器。

  • 不会执行延迟加载。
  • 你不能持久化或刷新此实体。
  • 当你想要比 Doctrine ObjectHydrator 快,但又不想插入/更新此实体,并且不保证可以访问未加载的属性时,非常有用。
  • ReadOnlyHydrator

填充你的实体的代理,如果你尝试访问未通过 QueryBuilder 加载的属性,将抛出异常。

  • 当你想要比 Doctrine ObjectHydrator 快,你不想插入/更新此实体,并且“确定”任何对未加载属性的访问都将抛出异常时,非常有用。
  • 你不能持久化或刷新此实体。
  • 当你想要比 Doctrine ObjectHydrator 快,但又不想插入/更新此实体,并且不保证可以访问未加载的属性时,非常有用。
  • 示例

安装

# Foo\Repository\BarRepository

use steevanb\DoctrineReadOnlyHydrator\Hydrator\ReadOnlyHydrator;

class BarRepository
{
    public function getReadOnlyUser($id)
    {
        return $this
            ->createQueryBuilder('user')
            ->select('user', 'PARTIAL comments.{id, comment}')
            ->join('user.comments', 'comments')
            ->where('user.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->getResult(ReadOnlyHydrator::HYDRATOR_NAME);
    }
}

安装

composer require steevanb/doctrine-read-only-hydrator ^2.3

Symfony 2.x 或 3.x 集成

# app/AppKernel.php

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = [
            new steevanb\DoctrineReadOnlyHydrator\Bridge\ReadOnlyHydratorBundle\ReadOnlyHydratorBundle()
        ];
    }
}

Symfony 4.x 或 5.x 集成

# config/bundles.php

return [
    steevanb\DoctrineReadOnlyHydrator\Bridge\ReadOnlyHydratorBundle\ReadOnlyHydratorBundle::class => ['all' => true],
];

手动集成

您需要将 SimpleObjectHydratorReadOnlyHydrator 注册到 Doctrine\ORM\Configuration

use steevanb\DoctrineReadOnlyHydrator\Hydrator\SimpleObjectHydrator;
use steevanb\DoctrineReadOnlyHydrator\Hydrator\ReadOnlyHydrator;

$configuration->addCustomHydrationMode(SimpleObjectHydrator::HYDRATOR_NAME, SimpleObjectHydrator::class);
$configuration->addCustomHydrationMode(ReadOnlyHydrator::HYDRATOR_NAME, ReadOnlyHydrator::class);

与 steevanb/doctrine-stats 集成

steevanb/doctrine-stats 为 Doctrine 添加了大量的统计信息:映射实体数量、懒加载实体数量、合并并计数相同的 SQL 查询、显示 hydration 时间等。

如果您使用这个库,您需要添加 SimpleObjectHydrator 和 ReadOnlyHydrator 的 hydration 时间。

# composer.json

{
    "extra": {
        "composer-overload-class-dev": {
            "steevanb\\DoctrineReadOnlyHydrator\\Hydrator\\SimpleObjectHydrator": {
                "original-file": "vendor/steevanb/doctrine-read-only-hydrator/Hydrator/SimpleObjectHydrator.php",
                "overload-file": "vendor/steevanb/doctrine-read-only-hydrator/ComposerOverloadClass/Hydrator/SimpleObjectHydrator.php"
            },
            "steevanb\\DoctrineReadOnlyHydrator\\Hydrator\\ReadOnlyHydrator": {
                "original-file": "vendor/steevanb/doctrine-read-only-hydrator/Hydrator/ReadOnlyHydrator.php",
                "overload-file": "vendor/steevanb/doctrine-read-only-hydrator/ComposerOverloadClass/Hydrator/ReadOnlyHydrator.php"
            }
        }
    }
}