关于O/R Mapping的思考,我们应该选择什么?(转)

理解O/R Mapping <br />本文的目的是以最精炼的语言,理解什么是O/R Mapping,为什么要O/R Mapping,和如何进行O/R Mapping。什么是O/R Mapping?<br />广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换。<br />狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口。理想情况下,基于这样一个面向对象的接口,持久化一个OO对象应该不需要要了解任何关系型数据库存储数据的实现细节。为什么需要O/R Mapping?< 阅读详情

最近对ORM方面的东西感兴趣,有一些想法,想和大家讨论一下。

我觉得Hibernate应算算是一个经典且功能强大的ORM框架。

它最大的有点是,你可以完全用面向对象分析与设计(OOAD)的思想来设计好所有的类,然后该框架就可以以非常人性化的方式为你获取对象或者持久化对象。

但同时我也发现它的一个缺点,就是当对象与对象之间的关系比较复杂的时候,ORM配置文件会很复杂,且比较难维护。并且当我们要对多个表进行关联查询时,虽然框架提供给了我们很多方便的接口让我们可以通过设置对象的属性的方式来告诉框架我们需要什么数据,然后框架会自动为我们生成一个复杂的SQL语句,最终返回给我们数据,但我发现当表关联较多并且数据量比较大的时候,往往性能不佳。

仔细想了之后,我觉得Hibernate的设计者的初衷是好的,就是想让我们尽可能的不用去关心数据库,让我们可以完全以面向对象的方式去实现我们的业务逻辑。但就我个人观点,我觉得它为我们做了太多的事情,比如一些原本属于业务逻辑的工作也由它帮我们自动完成了。比如订单(Order)和订单明细(OrderItem),一个Order包含了多个OrderItem,当我们要删除一个Order时,Hibernate能帮我们自动删除该订单下的所有OrderItem(当然你也可以选择不级联删除)。再比如,当我现在要显示一个帖子的详细页面,该页面需要显示帖子(Thread)内容以及所有的回复(Posts),如果用Hibernate,我们只需要查询一个Thread即可,而它下面的所有的Posts会自动被级联查询出来(因为我们已经在配置文件中配置好了,选择了非LazyLoad的情况时)。当然,你或许会觉得这样不是很好吗?全部自动化,你就很省心了,不是吗?确实,当业务逻辑比较简单时,这样没什么问题,但如果当业务逻辑比较复杂时,我们还能通过简单的不用动脑子的方式来配置映射关系,并且用简单的方式把数据查询出来吗?比如下面这个例子:

我现在要查询出一个论坛中某个版块下具有某种角色的所有用户,如果我们把这个角色理解为“版主”,那么就是相当于要查询出论坛中某个版块的所有的版主。
我可能会建如下一个表:

SQL code
   
CREATE TABLE [ tb_SectionRoleUsers ] ( [ SectionId ] [ int ] NOT NULL , [ RoleId ] [ int ] NOT NULL , [ UserId ] [ int ] NOT NULL )


SectionId表示版块ID,RoleId表示角色ID,UserId表示用户ID。对于这个表而言,必须是以两个字段组合去查第三个字段才有意义。比如查某个版块下具有某个角色的所有的用户,或者查某个版块下某个用户具有哪些角色。而如果仅仅根据一个字段作为查询条件进行查询是没有意义的,如查询某个版块下的所有的角色及用户,没有意义。

假设我们的用户表是下面这样的:

SQL code
   
CREATE TABLE [ tb_Users ] ( [ EntityId ] [ int ] IDENTITY ( 10000 , 1 ) NOT NULL , [ NickName ] [ varchar ] ( 64 ) NULL , [ AvatarFileName ] [ varchar ] ( 128 ) NULL , [ AvatarContent ] [ image ] NULL )



那么对于“查某个版块下具有某个角色的所有的用户”这个需求而言,我们需要的是关联上面这两个表,并且以SectionId和RoleId作为查询条件,查询出tb_Users表中的相关记录。

对于上面这个相对复杂的需求,我们该怎么利用Hibernate来配置映射关系并且该怎么样来设计对象呢?我相信Hibernate肯定可以,但估计要比我之前举的例子要复杂难懂的多吧。因为这里大概涉及到三个原子对象(Section、Role、User),并且这三个原子对象可能会两两进行组合,并且都是M:N的关系,并且必须要同时根据两个条件进行查询才有意义。

经过我的思考,我觉得之所以我们会觉得麻烦是因为我们把相当一部分业务逻辑都交给Hibernate来完成了,Hibernate帮我们做了非常多我们觉得很简单,而要告诉Hibernate该怎样做却是很麻烦的事情。其实tb_SectionRoleUsers表是一个关系表,在Hibernate中是不会有关系对象这个概念的,对象与对象之间的关系Hibernate可以帮我们自动维护,我们无需关心。而我们现在的需求就是想简单的将一个关系表和一个用户表关联,然后查询出符合条件的数据而已。

我觉得无论是表之间的各种关系还是对象之间的各种关系,都属于业务逻辑范畴,这些关系的实现不应该交给ORM框架自动完成,而应该由我们来自己完成比较好。

另外一个我发现的规律就是,数据库是关系型数据库,也就是说数据库里所有的表中存放的数据是没有直接关系的,可以说是扁平状(平行状)的,虽然有一些外键的约束,但我们不能认为两个表有外键约束就认为他们是一个包含的关系,最多是一个引用的关系。所以,表与表之间都是平行的关系,而非树状关系。但纯面向对象的思想则不一样,对象有包含或聚合的关系,可以说是一种具有多个跟节点的树状关系。这是两种完全不一样的存储数据方式。Hibernate的做法是,数据库这边没有做任何的妥协,对象这边也没做任何妥协,因此导致框架为了转换这两个存储格式完全不一样的数据必须要做非常复杂的映射;既然这样,我们为什么不同时稍微改变一下这两种数据格式呢,让数据库提供一些有关系的“东西”出来,比如建几个视图;而对于对象,不需要完全按照面向对象的思想来设计对象,而是也设计一些扁平状的对象出来,也就是说各个原子对象之间不明确知道它们之间的具体关系,当我们需要连接两个具有某种关系的对象时,我们可以像数据库的视图那样,设计一些组合对象出来,并且所有的这些原子对象以及组合对象也和数据库一样,是扁平结构。这些组合对象用于和数据库的视图建立映射关系。这样一来,对象和数据库两方都做了一些让步,但换来的结果是数据存储格式的统一,这样的好处就是ORM框架在也不用这么复杂难懂了。我觉得这样不是满好的吗?并且我觉得这样的设计到更有点像ROM了,因为我们的思路已经转到了以数据库为基准,然后稍微修改一下对象的设计,从而达到一个数据存储格式的一致。然后ROM框架基于这个前提,为我们提供一些实用的接口,为我们实现CRUD操作。相信这样的ROM框架的映射文件也是简单并且很好理解的。

好了,就这些吧,大家觉得我的想法如何呢?欢迎大家批评指正。

 

最后,基于我自己的这个想法,我经过长期的不断努力和改进,写了一个小型的ROM框架,思路完全和我上面说的一致。

大家可以看到对于任何数据请求,通过我的框架来处理,ROM配置文件以及对象设计或者业务逻辑是如何的简单。

 

下载地址:

http://www.cnblogs.com/netfocus/archive/2010/01/10/1643207.html

C++总结笔记 / ++操作 这是因为定义的数组,申请的是连续的内存空间,当ptr++(ptr是int类型的指针变量),地址空间向后偏移是以int类型的大小为单位进行偏移的,相当于int类型数组元素的向后偏移。使用场景:它是最通用的转换形式,用于将一种类型转换为另一种类型,例如基本数据类型的转换(如 float 转 int),指向基类的指针或引用转为指向派生类的指针或引用等。在派生类被调用时会调用派生类中的函数,不会调用基类中的被重写的函数(基类中的函数需要加上virtual才可以,即基类中的函数是虚函数)。 阅读详情

相关推荐

华硕笔记本键盘失灵恢复方法全解析

华硕笔记本键盘失灵问题可能由多种原因导致,但大多数问题都可以通过上述方法得到解决。在尝试恢复键盘功能时,请务必按照步骤操作,并注意备份重要数据。如果问题依然存在,请寻求专业维修人员的帮助。希望本文能够帮助大家快速解决华硕笔记本键盘失灵的问题!

mmoo_python的博客 4228

O/R Mapping 研究报告

1. 业务实体层的设计方案选择 1) 业务实体层的作用 一般的应用程序分层的结构如下: ...

weixin_30375427的博客 212

从SSD到UFS:3分钟搞懂存储技术进化史(含最新协议对比)

本文梳理了从SSD到UFS的存储技术演进历程,重点解析了eMMC与UFS在架构上的核心差异。UFS凭借高速串行全双工接口,实现了性能与能效的飞跃。文章还对比了最新的UFS 4.0与PCIe 5.0 SSD协议,并探讨了3D NAND、SLC缓存等底层技术,揭示了移动与PC存储技术融合的未来趋势。

weixin_29294597的博客 279

O/R Mapping 对象关系映射

ORM(Object-Relational Mapping)是一种将对象模型和关系型数据库之间的映射关系进行自动化转换的技术。ORM 的目标是将对象模型和关系型数据库之间的转换过程自动化,使开发人员可以使用面向对象的方式来操作数据库,从而提高开发效率和代码质量。对象和关系之间的映射关系定义。数据库操作的自动化,包括 CRUD 操作、事务管理等。

Hanhahahahah的博客 557

JMeter 中实现 100 个用户在 3 秒内并发登录

通过以上配置,你可以在 JMeter 中实现 100 个用户在 3 秒内并发登录

南开大学 | 10 年 + 软件研发与测试实战 | 现任企业质控负责人 | 专注端到端交付质量 1682

【DRAM存储器五十一】LPDDR5介绍--DFE与Pre-Emphasis

简述LPDDR5的DFE和预加重应用设置

highman110的博客 709

线型火灾探测器原理、测试与维护实战指南

火灾探测器作为消防系统的核心组件,其技术演进正从点型向线型发展。线型火灾探测器采用分布式传感原理,通过连续监测温度或烟雾变化实现早期预警,特别适用于电缆桥架、石油管道等长距离场景。相比传统点型探测器,其优势在于布线简化(节省60%施工成本)和覆盖范围广(单回路可达200米)。在工程实践中,需掌握标准测试方法:感温电缆需用专业热风枪加热,空气管式要控制测试气压,光纤式则需特定波长激光。维护时需重点关注连接器氧化和线路老化问题,使用DeoxIT等专业护理剂可有效预防故障。本文结合数据中心、地铁等实际案例,详解从

weixin_30887919的博客 390

基于Qt C++开发一套大疆农业无人机的AI飞控系统

如果需要补充**多机协同作业代码**、**农田测绘数据导出**、**作业数据统计大屏**或**移动端地面站适配**功能,可以告知具体需求,我会针对性完善。"开启" : "关闭") << "喷洒,流量:" << flowRate << "L/min";emit errorOccurred(QString("SDK初始化失败,错误码:%1").arg((int)ret));report += QString("问题区域数量:%1\n").arg(info.problemAreas.size());

寒寒豆豆软件公司的博客 382

什么是ORMapping?

ORM :对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),用于实现面向对象编程语言里不同类型系统的数据之间的转换。 O(面向对象)<----->ORMapping<----->R(面向关系) 在数据库层面, 尤其是关系型数据库. 是没有对象概念的. 有的只是表格, 和数据记录 想象一下, 如果你在某个视频网站, 为某个视频写了一条评论 接下来会发生什么呢? 我们要更改用户表...

qianfeng_dashuju的博客 755

译码器Multisim电路仿真汇总——硬件工程师笔记

本文详细介绍了74LS139D和74LS138D两种TTL译码器的功能特点及应用。74LS139D是2线-4线译码器,具有低电平有效输出和使能控制功能,常用于地址译码和数据分配。74LS138D是3线-8线译码器,通过3位输入实现8路输出控制,广泛应用于微处理器系统。文中提供了两种芯片的引脚说明、真值表和典型应用电路,并附有硬件工程师笔试面试相关资源链接。这些基础知识对数字电路设计和硬件工程师面试准备具有重要参考价值。

XU157303764的博客 1267

BevFusion (5):逐行代码详解

论文中给出了Bevfusion的架构图,它的输入是多视角的相机和点云图,经过两个特定的head,分别用于做检测任务和分割任务。图1 Bevfusion 结构图Bevfusion因为有两个模态的输入:多视角相机和点云,所以对应两个分支:相机分支和点云分支。相机分支:输入6个视角的图片后,提取特征,然后经VT(View Transformer)转换之后得到相机的Bev特征。激光雷达分支:输入点云数据,经过Encoder编码得到体素化Lidar特征,然后沿z方向展平,得到Lidar Bev特征。

@bangbang的博客 3715

O/R Mapping思考

玩O/R Mapping的体验,及由它想到的,胡思乱想,思维跳跃 转载于:https://www.cnblogs.com/William_Fire/archive/2005/06/06/168672.html

weixin_34319374的博客 120

基于STM32的智能浇花系统毕业设计(全部资料)

摘要:本文设计了一种基于STM32单片机的智能浇花系统,集成了环境温湿度检测、土壤温湿度监测、LCD显示、Wi-Fi联网及手机APP远程控制等功能。系统通过传感器实时采集环境参数,自动控制水泵工作实现智能灌溉,同时支持用户通过手机APP远程监控和调节。论文详细阐述了硬件选型、软件设计及系统测试过程,验证了系统的稳定性和实用性。该设计为家庭园艺提供了智能化解决方案,具有节水高效、操作便捷等特点。关键词:STM32;智能灌溉;远程控制;环境监测;Wi-Fi通信。

3254968421的博客 1196

实现自己的O/R Mapping组件

  我打算在业余时间写一个自己的、能够充分利用.NET特性O/R Mapping组件(能不能用不管它),基本的思路是研究代码生成器和一些成熟的O/R Mapping组件的思想来进行,如果有什么问题,大家请随时指正。我会不断地记录自己的开发与思考的过程,也当做一种形式上的开源吧。          实现自己的O/R Mapping组件[一]-概念解析 ...

weixin_34184561的博客 155

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

实现自己的O/R Mapping组件-高效缓存的思考

       首先,打算实现比较通用的一些功能,其中最通用的莫过于缓存的实现,这个无论在哪里都会有所应用,缓存的机制研究,也是这两天才开始的,十分汗颜的是,使用了那么久的缓存,到了该自己研究的时候,才发现这个小功能并没有想像中的那么简单,所幸的是,我不用像Hibernate那样,是用一个通用的平台上宝贝,要受到种种限制,这就给了我极大的思考空间---可以只考虑Windows平台下的实现。   ...

weixin_34199335的博客 107

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

实现自己的O/R Mapping组件[一]-概念解析

我打算在业余时间写一个自己的、能够充分利用.NET特性O/R Mapping组件(能不能用不管它),基本的思路是研究代码生成器和一些成熟的O/R Mapping组件的思想来进行,如果有什么问题,大家请随时指正。我会不断地记录自己的开发与思考的过程,也当做一种形式上的开源吧。 基本概念的研究 整体构思   目前的O/R Mapping要么是基于代码生成的,代码生成有时候较难以管理,但它却具有非常高的

zhiyang202_____________________________________________________________________ 1086

关于O/R Mapping的思考,我们应该选择什么?

最近对ORM方面的东西感兴趣,有一些想法,想和大家讨论一下。 我觉得Hibernate应算算是一个经典且功能强大的ORM框架。 它最大的有点是,你可以完全用面向对象分析与设计(OOAD)的思想来设计好所有的类,然后该框架就可以以非常人性化的方式为你获取对象或者持久化对象。 但同时我也发现它的一个缺点,就是当对象与对象之间的关系比较复杂的时候,ORM配置...

weixin_33717298的博客 97

从O-R Mapping的设计模式想到的 数据库静态字段的设计猜想

我们知道,Java EE经典框架Hibernate 采用即是O-R Mapping 设计模式,即模型(类)到关系(数据库表)的映射。它的核心思想是把类中的属性映射到数据库的表的各个字段中,我如是想到,类中可能会存在静态的属性(即所有该类对象皆可访问),那么数据库有没有设计成存在静

Devil_cpp的专栏 751

O/R Mapping与数据模型

说实话,我以前从没考虑这两者之间的关系,只是最近工作当中屡次遇到对这两者误用导致的问题,促使我思考这些问题,我遇到的问题有:1.DBA在建立数据模型时,为了在编码时方便,频繁地在一些进行数据冗余(在项目中,我就遇到过到处冗余过一个字段TypeId),而做这些的目的仅仅是为了编码时的方便(不用关联就可以取得一些字段值)与性能(若O/M,可以利用cache来提高性能),若没有使用O/M时,这种冗余还是

行云流水 1395

实现自己的O/R Mapping组件[二]-高效缓存的思考一(研究NHibernate的设计)

       缓存在O/R Mapping组件中是非常重要的,一个比较好的缓存方案,可以大大地提高对象的使用效率,避免内存空间上的浪费。目前需要在构思架构部分,但缓存的实现方式突然吸引了我,所以就对缓存进行一些思考,并研究了Gentle.NET与NHibernate的实现原理。 [这里的研究基于NHibernate 0.7.0] NHibernate的实现方案   在NHibernat...

weixin_33964094的博客 98

实现自己的O/R Mapping组件[二]-问题关注:昂贵的字段

  我所思考的组件,既不是一个持久层的框架,也不是一个简单的代码生成器,而且能够支持软件开发过程中的数据库重构行为的组件,有句名言说:“记录是免费的,字段是昂贵的”,指出了数据库架构的改动带来的灾难性的后果。我不指望目标中的组件可以可以解决这个问题,但我想通过在设计过程支持开发人员的设计来减轻字段带来的影响。具体请见下面的思考: 实现自己的O/R Mapping组件[二]-问题关注:昂贵的字...

weixin_33751566的博客 106

实现自己的O/R Mapping组件[三]-高效缓存的思考一(研究Gentle.NET)

缓存在O/R Mapping组件中是非常重要的,一个比较好的缓存方案,可以大大地提高对象的使用效率,避免内存空间上的浪费。目前需要在构思架构部分,但缓存的实现方式突然吸引了我,所以就对缓存进行一些思考,并研究了Gentle.NET与NHibernate的实现原理。 [这里的研究基于Gentle.NET 1.1.2] Gentle.NET的缓存实现方案   坦白说,打开Gen...

weixin_34104341的博客 88
上一篇: 使用微软分布式缓存服务Velocity Part 1
下一篇: 大话UML
ulark
博客等级 码龄17年 31粉丝 530原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值