对象关系映射

![]() |
物件关系映射(英语:Object–relational mapping,简称ORM,或O/RM,或O/R mapping tool)是电脑科学中的一种程式设计技术,用于在关系数据库和面向对象编程语言的内存(通常是堆)之间转换数据。这实际上创建了一个可在编程语言中使用的“虚拟物件数据库”。
在面向对象编程中,数据管理任务操作于将标量值组合为物件的物件。例如,一个包含个人资讯及多个电话号码和地址的地址簿条目。在面向对象实现中可建模为“Person物件”,其包含条目所组成的每个数据项的属性/字段:人名、电话号码列表和地址栏表。电话号码列表本身包含“PhoneNumber物件”等。每个地址簿条目被编程语言视为单个物件(例如可通过包含指向该物件指针的单个变量引用)。各种方法可与物件关系,例如返回首选电话号码、家庭地址等方法。
相比之下,如SQL等关系数据库将标量分组为元组,再枚举于表中。元组与物件有相似性(都将值收集到命名字段使整个集合可作为单个复合实体操作),但存在诸多差异:生命周期管理(行插入/删除 vs 垃圾回收/引用计数)、引用其他实体(物件引用 vs 外键引用)、继承(关系数据库中不存在)。物件在堆上管理且由单个进程完全控制,而数据库元组共享且需包含锁定、合并和重试。物件关系映射提供自动支持将元组映射到物件并返回,同时解决所有这些差异。[1]
问题核心在于将物件的逻辑表示转换为可存储于数据库中的原子化形式,同时保留物件及其关系的属性,以便需要时可重新加载为物件。若实现此存储检索功能,则称物件为持久的。[1]
概述
[编辑]存储驱动程式的实现细节通常封装在使用语言的API中,以更简洁且符合周边代码范型的方式暴露与存储介质交互的方法。
以下为使用C#代码的简单示例,通过数据库引擎执行SQL查询:
var sql = "SELECT id, first_name, last_name, phone, birth_date, sex, age FROM persons WHERE id = 10";
var result = context.Persons.FromSqlRaw(sql).ToList();
var name = result[0]["first_name"];
相比之下,以下利用ORM-job API可更自然地编写使用语言特性的代码:
var person = repository.GetPerson(10);
var firstName = person.GetFirstName();
上例使用代表存储库的物件及其方法。其他框架可能提供静态方法如下例,还有其他方法可能完全不实现面向对象系统。范型选择通常取决于ORM与周边语言设计原则的最佳契合。
var person = Person.Get(10);
与传统数据访问技术的比较
[编辑]相较于面向对象语言与关系数据库间交换的传统技术,ORM常减少需编写的代码量。[2]
ORM工具的缺点通常源于高层次抽象遮蔽了实现代码中的实际操作。
面向对象数据库
[编辑]另一方法是使用面向对象数据库管理系统(OODBMS)或面向文档数据库(如原生XML数据库)以提供更灵活的数据建模。OODBMS是专为处理面向对象值设计的数据库。使用OODBMS无需将数据转换为SQL形式,因数据以其原始物件形式存储且关系直接表示,无需联接表/操作。面向文档数据库的ORM等效物称为物件文件映射器(ODM)。
面向文档数据库还防止用户将物件"分解"为表行。许多此类系统也支持XQuery查询语言检索数据集。
面向对象数据库倾向用于复杂的利基应用。反对使用OODBMS的论点之一是其可能无法执行临时的、与应用无关的查询。[来源请求]因此许多程序员更习惯物件-SQL映射系统,尽管多数面向对象数据库能有限处理SQL查询。其他OODBMS提供到SQL数据库的复制,以满足临时查询需求同时保留已知查询模式。[来源请求]
挑战
[编辑]将物件系统匹配到关系数据库时会出现多种难题,称为物件关系阻抗不匹配。[3]
实现ORM的替代方案是使用每个主要数据库自带的原生过程语言。可通过SQL语句从客户端调用。数据访问物件(DAO)设计模式用于抽象这些语句,并为应用其余部分提供轻量级面向对象接口。[4]
ORM限于其预定义功能,可能无法涵盖所有边缘案例或数据库特性。通常通过提供编写原始查询的接口来缓解此限制,如Django ORM。[5]
参见
[编辑]- 对象关系映射软件列表
- 对象关系映射软件比较
- AutoFetch - 自动查询优化
- CORBA
- 对象数据库
- 对象持久化
- 对象关系数据库
- 对象关系阻抗不匹配
- 关系模型
- Java 数据对象
- Jakarta Persistence
- 服务数据对象
- Entity Framework
- 主动记录
- 数据映射器模式
- 单表继承
参考文献
[编辑]- ^ 1.0 1.1 What is Object/Relational Mapping?. Hibernate Overview. JBOSS Hibernate. [2022-01-27] (美国英语).
- ^ ((Barry, D.)), ((Stanienda, T.)). Solving the Java object storage problem. Computer (Institute of Electrical and Electronics Engineers (IEEE)). 1998, 31 (11): 33–40. doi:10.1109/2.730734.
此练习中,使用ODMG Java绑定需496行代码,而使用JDBC需1,923行。
- ^ 物件关系映射再探:数据库技术对O/R映射策略影响的定量研究。M Lorenz, JP Rudolph, G Hesse, M Uflacker, H Plattner。Hawaii International Conference on System Sciences (HICSS), 4877-4886 (DOI:10.24251/hicss.2017.592)
- ^ Feuerstein, Steven; Bill Pribyl. Oracle PL/SQL Programming. 18.5 修改持久物件. 1997-09 [2011-08-23] (美国英语).
- ^ 執行原始SQL查詢 | Django文檔. Django Project. [2024-09-08] (英语).
外部链接
[编辑]- 关于ORM (页面存档备份,存于互联网档案馆) by Anders Hejlsberg
- 将物件映射到关系数据库:O/R映射详述 (页面存档备份,存于互联网档案馆) by Scott W. Ambler