幕后制作:ORM如何"思考"?

Ale*_*zzi 5 php orm activerecord doctrine ruby-on-rails

我对Rails ActiveRecord,Doctrine for PHP(以及类似的ORM)背后的一些设计感兴趣.

  • ORM如何设法实现链式访问器等功能以及通常期望它们有多深?
  • ORM如何在内部构建查询?
  • ORM如何管理查询,同时维持所有预期的任意性质?

显然这是一个学术问题,但欢迎所有答案的性质!

(我选择的语言是OO PHP5.3!)

Ala*_*orm 3

链式方法调用与 ORM 问题正交,它们在 OOP 中随处可见。可链式方法仅返回对当前对象的引用,从而允许调用返回值。在 PHP 中

class A {
    public function b() {
        ...
        return $this;
    }

    public function c($param) {
        ...
        return $this;
    }       
}


$foo = new A();
$foo->b()->c('one');
// chaining is equivilant to
// $foo = $foo->b();
// $foo = $foo->c();
Run Code Online (Sandbox Code Playgroud)

至于如何构造查询,有两种方法。在像 ORM 这样的 ActiveRecord 中,有一些代码可以检查数据库的元数据。大多数数据库都有某种 SQL 或类似 SQL 的命令来查看此元数据。(MySQL的DESCRIBE TABLE、Oracle的USER_TAB_COLUMNS表等)

有些 ORM 让您使用中性语言(例如 YAML)描述数据库表。其他人可能会从您创建对象模型的方式推断数据库结构(我想说 Django 做到了这一点,但我已经有一段时间没有查看它了)。最后还有一种混合方法,使用前两种技术中的任何一种,但提供了一个单独的工具来自动生成 YAML/等。或类文件。

一旦表的名称和数据类型已知,就可以很容易地实用地编写返回所有行或满足特定条件的一组特定行的 SQL 查询。

至于你的最后一个问题,

ORM 如何管理查询,同时维持所有预期的任意性?

我认为答案是“不太好”。一旦超越了单表、单对象的比喻,每个 ORM 都有不同的方法和哲学来说明如何使用 SQL 查询来建模对象。但从抽象的角度来看,它就像添加基于 ORM 假设构造查询的新方法一样简单(即 Zend_Db_Table 的“findManyToManyRowset”方法)