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

Tom*_*man 4 php oop mapping orm

我打电话$user->get_email_address()怎么办?

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

public function get_email_address() {
    if (!$this->email_address) {
        $this->read_from_database('email_address');
    }
    return $this->email_address;
}
Run Code Online (Sandbox Code Playgroud)

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

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

public function get_email_address() {
    return $this->email_address;
}
Run Code Online (Sandbox Code Playgroud)

我的基本问题是,最好是最小化数据库查询的数量,或者最好是最小化从数据库传输的数据量.

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

一个后续问题:像Activerecord这样的ORM抽象框架有什么作用?

Dyl*_*tie 9

对此确实没有正确的答案.取决于您一次加载多少用户,您的用户表中有多少文本/ blob字段,无论您的用户表是否加载任何关联的子对象.正如aaronjensen所说,这种模式被称为延迟加载 - 而相反的行为(在你需要的时候加载所有内容)被称为渴望加载.

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

public function get_email_address() {
    if (!$this->email_address) {
        $this->load_all_data_from_db($this->id)
    }
    return $this->email_address;
}
Run Code Online (Sandbox Code Playgroud)

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


Aar*_*sen 6

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

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