【问题标题】:Using with() in Spot ORM在 Spot ORM 中使用 with()
【发布时间】:2015-02-28 16:13:30
【问题描述】:

我正在将Spot ORM 用于辅助项目。在文档中是这样写的

所有关系类型默认都是惰性加载的,可以通过with方法进行Eager-loading解决N+1查询问题:

$posts = $posts->all()->with('comments');

但是,Entity 没有这个方法,我只能在 Mapper 类中找到它,但它是受保护的(因此不可用)。我应该如何实现预加载?

【问题讨论】:

  • 如果它受到保护并不意味着它不可用。如果你引用的类是abstract,你必须从它扩展。
  • It is not :( 另外,documentation 使它看起来可以开箱即用
  • 你想在哪个类上使用with()函数?我假设不是 Mapper 类,因为您指出它是唯一具有这些功能的类。
  • 这实际上是我的问题,我应该在哪个班级使用它? :(

标签: php orm


【解决方案1】:

一般


来自documentation:

由于 Spot 遵循 DataMapper 设计模式,您将需要一个映射器实例来处理对象实体和数据库表。

映射器仅适用于一种实体类型,因此每个使用的实体类都需要一个映射器(即,要保存 Entity\Post,您将需要适当的映射器,而要保存 Entity\Comment,则需要评论映射器,而不是同一个帖子映射器。关系将由 Spot 由其对应的映射器自动加载和处理。

这意味着您必须为您的实体使用Mapper 类。

虽然您不必为每个实体创建一个映射器,但有时如果您有很多自定义查找器方法,或者想要一个更好的地方来包含构建您需要的所有查询的逻辑,那么创建一个映射器会很好。

这意味着如果您需要特定功能,您可以创建自己的Mapper 扩展(不是必需的)。除非您需要特定的逻辑,例如 finder 方法或其他自定义逻辑,否则 Spot 将为您加载通用映射器并返回它。

所以使用您自己的或通用的Mapper 并从那里使用with() 方法。请注意,受保护的字段不意味着它不可用。这只是意味着以 Mapper 为父类的类也获得了 with() 方法,而 with() 方法仍然是“私有的”,因此无法在类外访问。
正如您在链接的类中指定的那样,with() 方法受到保护,具有以下 cmets:

 /**
* Eager-load associations for an entire collection
*
* @internal Implementation may change... for internal use only
*/

您可以看到它被指定为仅供内部使用。请注意,这并不意味着它不能使用,它可以,但只能在Mapper 类内部使用。 Mapper 类中还有其他方法使用 with()

您的报价


您链接到的特定部分似乎是矛盾的,因为它看起来是指Entity,但我认为那里发生的是自定义Mapper。

如果您认为这是您的Post Entity:

namespace Entity;
class PostEntity extends \Spot\Entity
{
    protected static $mapper = 'Entity\Mapper\PostMapper';
    // ... snip ...
}

还有一个从Mapper延伸出来的:

namespace Entity\Mapper;
use Spot\Mapper;
class PostMapper extends Mapper
{

    //other methods

    //example method
    /**
    * Get 10 most recent posts for display on the sidebar
    *
    * @return \Spot\Query
    */
    public function mostRecentPostsForSidebar()
    {
        return $this->where(['status' => 'active'])
            ->order(['date_created' => 'DESC'])
            ->limit(10);
    }

    //other methods
}

您现在已经从 Mapper 扩展,所以现在您可以使用 with() 方法。
在PostMapper 中,您可以执行以下操作:

//Pseudocode
public function some_method()
{
    //Some code
    $this->with($collection, $entityName, $with);
    //Some code
}

请注意,PostMapper 在PostEntity 中也可以使用(作为static 字段)。希望你现在更清楚了。也许他们应该在文档的那部分指定它使用自定义Mapper。

【讨论】:

  • 谢谢,这有点令人失望,但我会同意的:D
  • 这就是像PostMapper 这样的命名法会有所帮助的地方。
  • @donquixote 是的,我不知道我为什么保留这些名字......我想我一定是从他们的示例代码中取出它们并且不想搞砸任何事情。我已经更新了它,所以现在希望它更清楚了。感谢您的提醒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多