我正在使用Spot ORM作为辅助项目。在文档中写了
默认情况下,所有关系类型都是延迟加载的,并且可以使用with方法急切加载以解决N + 1查询问题:
$posts = $posts->all()->with('comments');
但是,Entity没有这个方法,我只能在Mapper类中找到它,但它受到保护(因此不可用)。我该如何实施预先加载?
答案 0 :(得分:1)
由于Spot遵循DataMapper设计模式,因此您需要一个映射器实例来处理对象实体和数据库表。
Mappers只能使用一种实体类型,因此每个实体类需要一个映射器(即保存Entity \ Post,您需要相应的映射器,并保存实体\ Comment,您需要注释映射器,不是相同的post mapper。关系将由Spot的相应映射器自动加载和处理。
这意味着您必须为您的实体使用Mapper
课程。
虽然您不必为每个实体创建一个映射器,但如果您有很多自定义查找程序方法,或者想要一个更好的位置来包含构建所需查询的逻辑,有时可以创建一个映射器。
这意味着如果您需要特定功能,可以创建自己的Mapper
扩展名(不是必需的)。除非您需要特定的逻辑,例如finder方法或其他自定义逻辑,否则Spot会为您加载通用映射器并将其返回。
因此,请使用您自己的,或通用的Mapper
,并使用with()
方法。请注意,受保护的字段不表示它不可用。这只是意味着以Mapper
为父级的类也会获得with()
方法,而with()
方法仍为“私有”,因此无法在课堂外访问。<登记/>
正如您链接的类所指定的那样,with()
方法受到保护,并带有以下注释:
/**
* 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
。