为什么 ORM 被认为是好的,而“select *”被认为是不好的?

2023-12-23

ORM 通常不涉及执行诸如 select * 之类的操作吗?

如果我有一个表 MyThing,其中包含 A、B、C、D 等列,那么通常会有一个对象 MyThing,其属性为 A、B、C、D。

如果该对象没有被如下所示的 select 语句完全实例化,只获取 A、B,而不获取 C、D,那将是邪恶的:

select A, B from MyThing /* 不要获取 C 和 D,因为我们不需要它们 */

但总是这样做也是邪恶的:

select A, B, C, D /* 获取所有列,以便我们可以完整实例化 MyThing 对象 */

ORM 是否假设数据库访问速度如此之快,您现在不必担心它,因此您始终可以获取所有列?

或者,您是否有不同的 MyThing 对象,一个对应于 select 语句中可能出现的每一列组合?

编辑:在回答问题之前,请阅读 Nicholas Piasecki 和 Bill Karwin 的答案。我想我的问题问得不好,因为很多人都误解了,但尼古拉斯百分百理解。和他一样,我对其他答案感兴趣。


编辑#2:与此问题相关的链接:

为什么我们需要实体对象? https://stackoverflow.com/questions/18655/why-do-we-need-entity-objects

http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx,尤其是“部分对象问题和加载时间悖论”部分

http://groups.google.com/group/comp.object/browse_thread/thread/853fca22ded31c00/99f41d57f195f48b http://groups.google.com/group/comp.object/browse_thread/thread/853fca22ded31c00/99f41d57f195f48b?

http://www.martinfowler.com/bliki/AnemicDomainModel.html http://www.martinfowler.com/bliki/AnemicDomainModel.html

http://database-programmer.blogspot.com/2008/06/why-i-do-not-use-orm.html http://database-programmer.blogspot.com/2008/06/why-i-do-not-use-orm.html


根据我有限的经验,事情正如你所描述的那样——这是一个混乱的情况,通常的逃避“这取决于”的答案适用。

我工作的在线商店就是一个很好的例子。它有一个Brand对象,在网站的主页上,商店销售的所有品牌都列在左侧。要显示此品牌菜单,站点需要的只是整数BrandId和字符串BrandName。但是Brand对象包含一整套其他属性,最值得注意的是Description可以包含大量有关该属性的文本的属性Brand。没有两种方法可以解决这个问题,加载有关该品牌的所有额外信息只是为了在无序列表中吐出其名称,这是(1)明显且明显缓慢的,通常是因为文本字段很大,并且(2)当它出现时效率非常低内存使用情况,构建大字符串,甚至在扔掉它们之前都不看它们。

许多 ORM 提供的一种选项是延迟加载属性。所以我们可以有一个Brand对象返回给我们,但是那个耗时又浪费内存Description直到我们尝试调用它的字段get访问器。此时,代理对象将拦截我们的调用并及时从数据库中获取描述。有时这已经足够好了,但已经让我很恼火了,我个人不推荐它:

  • 人们很容易忘记该属性是延迟加载的,仅通过编写 foreach 循环就会引入 SELECT N+1 问题。谁知道当 LINQ 介入时会发生什么。
  • 如果即时数据库调用因传输混乱或网络故障而失败怎么办?我几乎可以保证任何代码都会做一些无害的事情string desc = brand.Description没想到这么简单的调用就扔了一个DataAccessException。现在你刚刚以一种令人讨厌且意想不到的方式崩溃了。 (是的,我已经看到我的应用程序因此而严重下降。经历了惨痛的教训!)

因此,我最终所做的是,在需要性能或容易出现数据库死锁的情况下,我创建一个单独的接口,网站或任何其他程序可以调用该接口来访问已进行查询的特定数据块计划经过仔细审查。该架构最终看起来有点像这样(原谅 ASCII 艺术):



Web Site:         Controller Classes
                     |
                     |---------------------------------+
                     |                                 |
App Server:       IDocumentService               IOrderService, IInventoryService, etc
                  (Arrays, DataSets)             (Regular OO objects, like Brand)
                     |                                 |
                     |                                 |
                     |                                 |
Data Layer:       (Raw ADO.NET returning arrays, ("Full cream" ORM like NHibernate)
                   DataSets, simple classes)
  

我曾经认为这是作弊,颠覆了OO对象模型。但从实际意义上来说,只要你做到这个显示数据的快捷方式,我觉得就可以了。更新/插入以及您仍然需要经历完全水合、ORM 填充的域模型,而这种情况发生的频率远低于显示特定数据子集(在我的大多数情况下)。像 NHibernate 这样的 ORM 可以让你进行投影,但到那时我还没有看到 ORM 的意义。无论如何,这可能是一个存储过程,编写 ADO.NET 需要两秒钟。

这只是我的两分钱。我期待着阅读其他一些回复。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 ORM 被认为是好的,而“select *”被认为是不好的? 的相关文章

  • getCurrentSession 在网络中休眠

    我正在使用 hibernate 和 jsp servlet 编写一个基于 Web 的应用程序 我读过有关sessionFactory getCurrentSession and sessionFactory openSession方法 我知
  • 如何将事物的组合映射到关系数据库?

    我有一个表 其记录代表某些对象 为了简单起见 我假设该表只有一列 这是唯一的ObjectId 现在我需要一种方法来存储该表中的对象组合 组合必须是唯一的 但可以是任意长度 例如 如果我有ObjectIds 1 2 3 4 我想存储以下组合
  • 如何在 Hibernate 拦截器中获取 Hibernate 会话?

    如何在 Hibernate 拦截器中获取 Hibernate 会话 我正在尝试使用 Hibernate 透明地强制按组织 ID 进行数据访问 我设置了一个全局过滤器来按组织 ID 过滤所有查询 现在 我需要在保存 更新之前使用实体拦截器在所
  • CakePHP hasOne/belongsTo 模型关系

    我有几个模型正在尝试关联 一种模型是Item 一个是Slide 另一个是Asset 项目下方有多个幻灯片 资产基本上是已上传的文件 图像 mp3 等 幻灯片是显示资产的位置 每张幻灯片都有一个资产 但给定的资产可能属于多张幻灯片 一张幻灯片
  • Bool类型返回规则

    我使用 dapper ORM 所以我使用两个规则Query
  • Hibernate、MySQL 视图和 hibernate.hbm2ddl.auto = 验证

    我可以在 Hibernate 中使用 MySQL 视图 将它们视为表 即 该实体与为表创建的实体没有什么不同 但是 当 Hibernate 设置为验证模型时 我的应用程序将不会部署 因为它找不到视图 因为它假设它是一个表 是否可以在启用部署
  • 如何删除django中级联的一对一相关模型?

    背景 我在 Django 1 8 5 中定义了以下模型 class PublishInfo models Model pass class Book models Model info models OneToOneField Publis
  • Hibernate 标准接受 %% 值

    我正在使用下面的 Hibernate 代码来过滤workFlowName crt add Restrictions like workFlowName workFlow MatchMode ANYWHERE crt is the crite
  • SugarORM 错误或缺少数据库

    我尝试让 Android 项目与 SugarORM 一起使用 但是 我遇到了以下错误 引起原因 android database sqlite SQLiteException 没有这样的表 DOCUMENT 代码1 编译时 INSERT O
  • 将 Django +1.10 与 MongoDB 连接

    在过去的几个月里 有人为 MongoDB 更换了 Django 1 10 中的默认数据库引擎吗 我在谷歌上得到的所有信息都是六四年前的 最常见的结果包括mongodb 引擎这需要Django nonrel 来自 Django 1 5 的一个
  • 具有 LINQ 支持的最完整的 ORM?

    我正在寻找一个提供完整或接近完整的 LINQ 支持的 ORM LINQ 到 SQL 支持 LINQ 内部的所有内容 Contains Math Log 等 在不创建新数据上下文的情况下无法预先加载关系属性 ADO NET 实体框架 糟糕的
  • Sequelize 4.3.2 n:m(多对多)关联:未处理的拒绝 SequelizeEagerLoadingError

    我有 3 个模型 用户 项目 UserProject module exports function sequelize DataTypes var User sequelize define User title DataTypes ST
  • SQLAlchemy 如何使用“完全模块限定路径”?

    我正在为一个使用 sqlalchemy 的项目做出贡献 该项目有一个 model py 文件 其中定义了所有类 例如Foobar BASE 现在 我已经创建了another模块 mymodel py 我需要扩展其中一些类 例如 在 mymo
  • Laravel Eloquent with()-> 返回 null

    我正在尝试使用 Eloquent 来获取具有以下功能的特定产品 brand id映射到a的列brands表 该brand数组返回空 这里有什么明显需要改变的地方吗 product Product with images gt with br
  • 如何在 Hibernate 中使用 SELECT 进行 INSERT

    我需要在休眠中实现以下请求 insert into my table max column values select max id from special table where 如何在休眠中使用注释来做到这一点 Special tab
  • 使用 DataMapper 而不是 ActiveRecord [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 JPA 从集合中删除子项

    我在我的网络应用程序中使用 JPA 而不是 Hibernate 这是两个实体 仅显示 getter class Child private Parent parent ManyToOne optional false JoinColumn
  • Id 或 [TableName]Id 作为主键/实体标识符

    是否首选使用 Id 作为主键的列名或 TableName Id 作为命名约定 表 账户主键 ID 相对 表 账户主键 AccountId 在我见过的实现中 它似乎分为 50 50 左右 每种方法的优点和缺点是什么 跟进 在我的数据库中使用一
  • spring 如何允许延迟加载?

    如果您在 Dao 方法中有一个调用 例如 伪代码 return getHibernateTemplate 通过 id 获取 现在假设该实体有一个延迟加载的集合 使用 hibernateTemplate 辅助方法从 Dao 返回后 会话如何保
  • 在 PlayFramework 2 / Ebean ORM 中使用 @OneToOne,其中子级和父级共享相同的主键

    有两种型号 模型 User java Entity Table name users public class User extends Model Id public int user id public String firstName

随机推荐

  • JAX-RS和自定义授权

    我正在尝试保护 JAX RS 端点 目前正在尝试弄清楚身份验证和授权是如何工作的 大多数示例都非常简单 因为它们仅通过 web xml 搭载 Java EE 应用服务器角色 我想知道如何使用 Java EE AS 角色之外的其他角色 例如
  • Couchbase Lite 2 + JsonConvert

    以下代码示例将一个简单的对象写入 couchbase lite 版本 2 数据库 然后读取所有对象 这个你可以在官方文档中找到here https developer couchbase com documentation mobile 2
  • 在 Chrome 扩展中运行喊播广播

    我想为我的网络shoutcast网络广播电台创建一个chrome扩展 我设法使这一切正常工作 除了每当我点击弹出窗口时 它就会关闭 并且流也会随之停止 读了一点之后 我发现我需要创建一个后台页面 这将使播放器在后台运行 这就是我迷失和困惑的
  • 如何强制浏览器不存储 HTML 表单字段数据?

    在 HTML 表单中输入内容时 Firefox 或 Internet Explorer 等浏览器会存储这些值 有时会悄悄存储 因此 当输入另一个网络表单时 浏览器会智能地建议相同的信息 显示下拉列表的另一种方法是双击空文本框 在电子商务网站
  • Python读取设备管理器信息

    我只需要使用 python 2 7 脚本读取设备管理器中列出的所有信息 特别是 IDE ATA ATAPI 控制器 子类别下的信息 需要检测 SATA 驱动器是否处于 AHCI 或 IDE 模式 一种简单的方法 在 Windows 上 是使
  • multer、multiparty 和 connect-multiparty + Nodejs 之间的区别

    我是 Node 世界的新手 用例 有一个在 Angular 前端上传 XLS 文件的简单场景 在 Node 上处理它们 进行一些操作 然后将 JSON 保存到 蒙戈数据库 从 Angular 收到文件后 我正在搜索在 Node 上解析 处理
  • ARKit Stereo – 是否可以同时运行两个 ARSCNView?

    我正在考虑对现有的 AR 应用程序进行一些修改 我想拆分视图并添加内部 2ARSCNView这样用户就可以使用VR卡盒并获得不同的体验 但Xcode总是返回给我 Session 0x102617d10 did fail with error
  • 如何在 UITextView 中显示可点击的链接

    我正在尝试在 UITextview 中显示带有可单击链接的属性字符串 我创建了一个简单的测试项目来看看哪里出了问题 但仍然无法弄清楚 我尝试启用用户交互并设置 shouldInteractWithURLs 委托方法 但它仍然不起作用 这是我
  • 为什么 CoreNLP ner tagger 和 ner tagger 将分开的数字连接在一起?

    这是代码片段 In 390 t Out 390 my phone number is 1111 1111 1111 In 391 ner tagger tag t Out 391 my O phone O number O is O 111
  • 反转数组顺序

    我正在尝试反转 java 中数组的顺序 在 O n 内使用最少的内存来完成此操作的最有效方法是什么 不需要用代码回答 伪代码就可以了 这是我的思考过程 create a new temp array I think this is a wa
  • jquery 与更新面板

    我在使用 jquery 上下文菜单和更新面板时遇到问题 我正在使用 htmlTextWriter 在 Customtextbox 控件的 RenderBeginTag 中编写上下文菜单的 javascript 一切正常 我可以右键单击每个文
  • 在 TRichEdit 中加载包含表格但没有表格边框的 RTF 文件

    我有一个 RTF 文件 正在将其加载到 TRichEdit 控件中 我面临的唯一问题是 RTF 文件中有表格 加载相同的文件会显示表格边框 但是当我在 MS Word 中加载相同的 RTF 时 它不显示任何边框 客户端想要相同的行为 有没有
  • raster可以创建不同模式的多层对象吗?

    Can a raster对象 R 中 具有不同模式 数据类型 的层 从表面上看 我们似乎总是被迫选择一种类型 library raster create a SpatialPixelsDataFrame with trivially two
  • 如何在Matlab中删除wav文件的标题

    我需要删除波形文件的前 1024 个字节 我尝试这样做 但我得到了损坏 扭曲的 wavfile wavFile fopen fullFileName r Open file for reading fseek wavFile 1024 1
  • Python 创建带有反馈的迭代器/生成器

    是否可以创建一个迭代器 生成器 它将根据某些值决定下一个值result在上一次迭代中 i e y None for x in some iterator ll y y some calculation on x 我想要选择下一个的逻辑x依赖
  • C# 构造函数线程安全吗?

    假设我有多个线程 每个线程都试图创建同一类的对象 不同线程同时创建同类型的对象会不会互相干扰 我需要在构造函数中使用 锁 吗 这在很大程度上取决于构造函数的实现 如果构造函数仅访问该类的成员 而不访问任何外部静态类或方法 那么是的 它是线程
  • Android BLE BluetoothGatt.writeDescriptor() 有时返回 false

    我正在尝试编写 BLE Android 应用程序 我发现有时当我打电话时BluetoothGatt writeDescriptor https developer android com reference android bluetoot
  • 链接到断开连接的 ADODB.Recordset 的访问表单:保存更改

    我正在尝试设置一个表单以使用断开连接的 ADODB Recordset 作为其源 我遇到的问题是变化是not关闭表单并对提示回答 是 后 将其保存到原始 Access 表中 我缺少什么 注意 请不要告诉我该方法没有用 它只是一个具有本地表的
  • 通用 DbDataReader 到 List 映射

    我的属性绑定数据访问类遇到了一个小问题 更像是烦恼 问题是 当读取器中不存在类中相应属性的列时 映射会失败 Code 这是映射器类 Map our datareader object to a strongly typed list pri
  • 为什么 ORM 被认为是好的,而“select *”被认为是不好的?

    ORM 通常不涉及执行诸如 select 之类的操作吗 如果我有一个表 MyThing 其中包含 A B C D 等列 那么通常会有一个对象 MyThing 其属性为 A B C D 如果该对象没有被如下所示的 select 语句完全实例化