对象关系映射:实现getter的最佳方法是什么?

时间:2008-10-04 05:42:14

标签: php orm oop mapping

当我致电$user->get_email_address()时会发生什么?

选项1:根据需要从数据库中提取电子邮件地址

public function get_email_address() {
    if (!$this->email_address) {
        $this->read_from_database('email_address');
    }
    return $this->email_address;
}

选项2:在创建对象时从数据库中提取电子邮件地址(和其他用户属性)

public function __construct(..., $id = 0) {
    if ($id) {
        $this->load_all_data_from_db($id);
    }
}

public function get_email_address() {
    return $this->email_address;
}

我的基本问题是,最好是最小化数据库查询的数量,还是最好尽量减少从数据库传输的数据量。

另一种可能性是,最好加载您最需要的属性/在创建对象时包含最少的数据以及其他所有需要的属性。

后续问题:像Activerecord这样的ORM抽象框架做了什么?

3 个答案:

答案 0 :(得分:9)

这确实没有正确的答案。取决于您一次加载多少用户,您的用户表中有多少文本/ blob字段,无论您的用户表是否加载任何关联的子对象。正如aaronjensen所说,这种模式被称为延迟加载 - 而相反的行为(在你需要的情况下预先加载所有)被称为渴望加载< / strong>即可。

也就是说,您可能需要考虑第三个选项,即在访问任何属性时延迟加载整个User对象:

public function get_email_address() {
    if (!$this->email_address) {
        $this->load_all_data_from_db($this->id)
    }
    return $this->email_address;
}

这种方法的优点是你可以根据他们的ID创建一组用户(例如,密码为空的所有用户的列表?),而没有完全加载每个用户的内存命中,但是您只需要为每个用户调用一个数据库来填充其余的用户字段。

答案 1 :(得分:6)

尽量减少查询次数。最佳查询数为0,但是如果你必须查询,因为它没有被缓存,那就是1.查询每个属性对于一个永远不会扩展的系统来说是一种可靠的方法,会产生大量的争用问题,并且会导致比它的价值。

我应该提到延迟加载有价值(这是你在步骤1中讨论的内容)如果你不太可能需要延迟加载数据。如果可以的话,最好是明确的,并准确或几乎完全取得你需要的东西。查询花费的时间越少,连接打开的时间就越短,系统的可扩展性就越高。

答案 2 :(得分:0)

我同意aaronjensen的意见,除非您提取的数据量非常大,以至于您将开始耗尽过多的内存。我在想一行有3个文本字段都非常大,你想要的只是ID字段。