在Spot ORM中使用with()

时间:2015-02-28 16:13:30

标签: php orm

我正在使用Spot ORM作为辅助项目。在文档中写了

  

默认情况下,所有关系类型都是延迟加载的,并且可以使用with方法急切加载以解决N + 1查询问题:

     

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

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

1 个答案:

答案 0 :(得分:1)

一般


来自documentation

  

由于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
}

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