好吧,每当我们进行这样的讨论时,要做的一件重要的事情就是清楚地区分对象关系映射器(“ ORM”)和数据库抽象层。ORM是一种数据库抽象层,但并非所有数据库抽象层都是ORM。研究这一问题的一个好工具是Python流行的SQLAlchemy库,该库自称为“ SQL工具箱和对象关系映射器”(我的黑体字),认为它们是不同的东西。正如他们在其主要功能页面中所述:
无需ORM
SQLAlchemy由两个不同的组件组成,称为Core和ORM。Core本身是功能齐全的SQL抽象工具包,可为各种DBAPI实现和行为提供平滑的抽象层,以及一种SQL Expression Language,该语言可通过生成的Python表达式表达SQL语言。一个既可以发出DDL语句又可以对现有模式进行内省的模式表示系统,以及一个允许将Python类型映射到数据库类型的类型系统,可以完善该系统。然后,对象关系映射器是基于Core构建的可选包。
首页描述了这样的ORM:
SQLAlchemy最著名的是对象关系映射器(ORM),它是提供数据映射器模式的可选组件,在该模式中,可以以开放式,多种方式将类映射到数据库-允许对象模型和数据库模式以从一开始就完全脱钩。
ORM的关键思想是尝试消除著名的对象关系阻抗不匹配。这意味着定义用户定义的类与数据库模式中的表之间的关系,并为应用程序的类提供自动的“保存”和“加载”操作。
相反,非ORM数据库抽象层倾向于更致力于关系数据模型和SQL,而不是完全面向对象。因此,与其在表和类之间不提供“映射”并向程序员隐藏数据库模式,不如将它们向数据库公开给程序员,但具有更好的API和抽象。例如,SQL查询构建器允许您以编程方式生成复杂的SQL查询,而无需进行字符串操作(例如,来自Java的jOOQ库的示例):
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.from(BOOK)
.join(AUTHOR)
.on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
.where(BOOK.PUBLISHED_IN.equal(1948))
.fetch();
现在,Play框架似乎与我刚刚描述的并不完全相同,但他们的论点似乎是在这个大致领域内:直接使用关系模型,而不是将其转换为类并从中转换回来。
该jOOQ库是值得研究的一个对应的ORM。他们也有一些相关的博客条目,值得一读: