我承认,我没有完全grok * Hibernate。
由于像Dapper这样的微型ORM可用于解决大多数数据访问需求,需要像nHibernate这样的大枪的场景是什么? nHibernate闪耀的情况有哪些例子?要明确的是,我不认为“在不改变代码的情况下切换数据库的能力”太有利了。在八年的编程中,我从来没有真正做过这样的事情,这似乎是一个浪费时间的开始。
我愿意接受任何深思熟虑的回应,但这里有一些问题的例子:
答案 0 :(得分:8)
我认为简短的回答是,当您的数据库需求达到一定程度的复杂性时,满足您的需求的成本会低于nhibernate学习曲线所涉及的成本。我无法提供完整的答案,但会尝试对您的列表项进行思考。
我只是谈到nHibernate,但我想Hibernate的故事大致相同。对于更大规模,更复杂的应用程序,可以带来很多好处,但是为了获得这些好处,还需要承担很多额外的复杂性 - 它仍然可能不如将自己的解决方案应用于所有问题那么复杂* Hibernate为您解决。
你似乎也有很多关于缓存的问题。我建议阅读this link以了解第一级和第二级缓存的工作原理。我不会在这里解释,因为听起来你的理解比我对这个已经冗长的回复更深刻的理解:)
答案 1 :(得分:5)
NHibernate功能强大,但您不必了解它的一切,才能成功使用它。回答你的问题:
所有.NET micro-ORMS都没有我所知道的LINQ支持,而是依赖于在代码中混合使用SQL字符串。使用LINQ构建查询为您提供类型安全性,编译时检查和极佳的可重构性。如果所有查询都使用SQL字符串,请尝试使用数千个查询重构代码库... yikes!通过重构,我的意思就像添加新列,新表等一样简单,这是在企业环境中一直发生的事情。重构字符串是可能的,那就是人们仍然需要做的依赖存储过程的东西,但如果我有自己的类型安全性,我肯定不会选择这样做。
使用延迟加载时,您唯一需要记住的是创建SELECT N + 1场景。每当你有代码在域对象/实体上执行foreach循环时,请确保填充对象的查询使用.Fetch()方法,该方法只是在SQL中创建JOIN并填充所有子对象。否则,当您遍历对象并插入任何子对象时,ORM将必须执行另一个SELECT语句来“获取”数据。基本上,在NHibernate术语中,渴望获取是你的朋友。
批处理与NHibernate一样简单。在你的NHibernate配置中,打开批处理就是这样。之后,如果确实需要,可以在运行时调整批量大小以进行特定查询。
我自己从未使用过二级缓存。我在一个大型企业环境中工作,我们的应用程序运行速度非常快,无需缓存。 NHibernate中的第一级缓存虽然不需要配置,但可以简单地将其视为更改跟踪。基本上,内部NHibernate会保存一个字典,其中包含已从数据库中检索的对象以及要在数据库中保存/更新的对象。第一级缓存是我从未真正考虑过的事情,但我想在最基本的层面知道它是如何工作的。
同样,我目前在企业环境中工作,我们有各种使用NHibernate的应用程序;一些非常基本的和其他使用NHibernate提供的所有强大功能。我通常在我的经验中看到的是,并非团队中的每个成员都需要成为NHibernate专家。通常情况下,1-3个开发人员将非常了解,其他人都不会担心它,只需创建他们的实体,映射,并继续他们的编程。一旦基础设施到位并且您的组织已经整理出它希望使用的模式,一切都通常是轻而易举的。
其他想法:
NHibernate真正发挥作用的一个地方是它能够映射你抛出的任何疯狂的数据库设计。现在我并不是说在90年代早期将一些疯狂的数据库设计映射到一起很容易,你必须加入存储过程和另一个表,但 是可能的。我在那一天做了一些疯狂的映射。有些人甚至认为这是不可能的,因为数据库并不是为了做我们想做的事情而设计的,但每次使用持久性,我仍然设法通过NHibernate在映射好的和坏的数据库设计方面具有令人难以置信的灵活性。
使用Micro-ORMS,您通常会在代码中嵌入大量SQL字符串。这怎么被认为是干净和有效的。看起来所有人都在做的就是将他们用来存储过程放在他们的代码中。我实际上在我的一些项目中使用Micro-ORM虽然它有意义,但通常当我只在一个表上查询一些简单的数据时 - 没有复杂的WHERE子句。
公平地说,我是那些投入了大量时间学习NHibernate的来龙去脉的人之一,但不是因为我需要工作,而是因为我只是想。我和很多工作的人一起工作,他们每天都在使用NHibernate并且没有完全掌握它。但同样,他们不需要。你只需要了解一些基本的东西,你就可以去了。
希望这有帮助。