jeremyharris/cakephp-lazyload

此包的最新版本(5.0.0)没有可用的许可证信息。

CakePHP ORM 关联式懒加载器

安装数: 452,966

依赖者: 3

建议者: 0

安全: 0

星标: 61

关注者: 8

分支: 10

开放性问题: 4

类型:cakephp-plugin

5.0.0 2023-10-04 17:31 UTC

This package is not auto-updated.

Last update: 2024-09-13 18:01:47 UTC


README

Packagist license

CakePHP ORM 懒加载插件

这是一个为 CakePHP ORM 实体设计的关联式懒加载器。它允许您通过访问属性来懒加载关联数据,而不必使用 contain()(贪婪加载器)。

安装

要求

  • CakePHP ORM(或完整框架)5.x
  • sloth

$ composer require jeremyharris/cakephp-lazyload

对于 CakePHP ORM 的旧版本,请查看此库的旧版本。

使用方法

如果您有一个基本实体,添加特质以在整个实体上启用懒加载。或者,将其附加到单个实体上,仅在该实体上启用懒加载

src/Model/Entity/User.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;
use JeremyHarris\LazyLoad\ORM\LazyLoadEntityTrait;

class User extends Entity
{
    use LazyLoadEntityTrait;
}

现在可以从实体中懒加载 Users 表的关联了!

示例

假设我们的基本实体具有 LazyLoadEntityTrait 特质

Brewery hasMany Beers
Programmer belongsToMany Beers

使用懒加载器,我们只需要实体

<?php
// get an entity, don't worry about contain
$programmer = $this->Programmers->get(1);

当访问关联属性时(就像数据已经贪婪加载一样),关联数据将自动加载。

<?php
// beers is lazy loaded
foreach ($programmer->beers as $beer) {
    // brewery is lazy loaded onto $beer
    echo $programmer->name . ' drinks beer ' .  $beer->name . ' from ' . $beer->brewery->name;
}

使用 contain 与懒加载器结合使用

懒加载器不会覆盖由贪婪加载器(contain())生成的结果。您仍然可以编写复杂的 contain 条件并利用懒加载器。

<?php
$programmer = $this->Programmers->get(1, [
    'contain' => [
        'Beers'
    ]
]);

// beers is loaded via the eager loader
$programmer->beers;
// brewery is lazy loaded onto $beer[0]
$programmer->beers[0]->brewery;

实体方法支持

具有懒加载器特质的实体支持使用 Cake ORM 提供的不同属性访问方法进行懒加载

  • 获取器:$programmer->get('beers')$programmer->beers
  • 存在:$programmer->has('beers')
  • 取消设置:$programmer->unsetProperty('beers')

通过 Entity::unsetProperty() 取消设置属性时,将防止在将来对该实体进行懒加载,因为它以类似于典型实体的方式尊重状态。如果您希望重新填充关联,可以使用 ORM 提供的 Table::loadInto

<?php
$programmer = $this->Programmers->get(1);

// beers is lazy loaded
$programmer->beers;
// remove beers from the entity
$programmer->unsetProperty('beers');
// this now returns false
$programmer->has('beers');
// if we want access to beers again, we can manually load it
$programmer = $this->Programmers->loadInto($programmer, ['Beers']);

测试

有时在测试中,我们创建的实体可能没有表。当访问一个不存在的属性时,LazyLoad 特质将尝试加载表以获取关联数据,如果表不存在,则会引发错误。为防止这种情况,您可以在实体中重写 _repository()

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;
use Exception;
use JeremyHarris\LazyLoad\ORM\LazyLoadEntityTrait;

class User extends Entity
{
    use LazyLoadEntityTrait {
        _repository as _loadRepository;
    }

    protected function _repository()
    {
        try {
            $repository = $this->_loadRepository();
        } catch (Exception $e) {
            return false;
        }
        return $repository;
    }
}

默认情况下,LazyLoad 特质会抛出 TableRegistry::get() 弹出的任何错误。

插件

如果测试没有表的插件实体,请确保重写 _repository() 方法以返回 插件 的表。

注意事项

  • Contain: 这不是 contain() 的替代品,后者可以编写复杂的查询以指定要包含的数据。懒加载器遵守您在表上定义关联时设置的关联条件,但除此之外,它会获取所有关联数据。
  • 速度: 以这种方式进行懒加载并不一定提高速度。事实上,在某些情况下,它可能会降低速度,例如在循环中遍历懒加载关联的实体(为每个项目创建单个 SQL 查询而不是使用连接或 ORM)。此插件旨在作为启动项目的辅助工具。
  • 数据初始化:懒加载器需要您的结果集进行初始化,以便提供懒加载功能。

特别感谢@lorenzo在插件最初发布前对其进行审查!