jmq*_*jmq 68 java hibernate jdbc
我有一个胖客户端,java swing应用程序,具有25个表的模式和~15个JInternalFrames(表的数据输入表单).我需要在DBMS交互中进行直接JDBC或ORM(在这种情况下使用spring框架进行hibernate)的设计选择.应用程序的构建将在未来发生.
对于这么大的项目,hibernate是否会过度杀伤?对是或否答案的解释将非常感激(如果有必要,甚至是不同的方法).
TIA.
Gre*_*zky 184
好问题没有一个简单的答案.
在多年的多个项目中使用它之后,我曾经是Hibernate的忠实粉丝.我曾经相信任何项目都应该默认为休眠.
今天我不太确定.
Hibernate(和JPA)对某些事情很有用,尤其是在开发周期的早期阶段.使用Hibernate比使用JDBC要快得多.您可以免费获得许多功能 - 缓存,乐观锁定等.
另一方面,它有一些隐藏的成本.当你开始时,Hibernate很简单.按照一些教程,在你的课上加上一些注释 - 你就有了自己的坚持.但它并不简单,能够在其中编写好的代码需要很好地理解它的内部工作和数据库设计.如果你刚刚开始,你可能不会意识到一些可能会在以后咬你的问题,所以这里有一个不完整的列表.
性能
运行时性能足够好,我还没有看到hibernate是生产性能不佳的原因.问题是启动性能以及它如何影响单元测试时间和开发性能.当hibernate加载时,它会分析所有实体并执行大量预缓存 - 对于不是很大的应用程序,它可能需要大约5-10-15秒.所以你的1秒单位测试现在需要11秒.不好玩.
数据库独立性
只要您不需要对数据库进行一些微调,它就非常酷.
内存会话
对于每个事务,Hibernate都会在内存中为它"触摸"的每个数据库行存储一个对象.当您进行一些简单的数据输入时,这是一个很好的优化.如果由于某种原因需要处理大量对象,则会严重影响性能,除非您自己明确并仔细地清理内存中的会话.
瀑布
Cascades允许您简化对象图的使用.例如,如果您有一个根对象和一些子节点并且保存了根对象,则可以配置hibernate来保存子节点.当对象图变得复杂时,问题就开始了.除非你非常小心并且对内部发生的事情有很好的理解,否则很容易弄清楚这一点.当你这样做时,很难调试这些问题.
延迟加载
延迟加载意味着每次加载对象时,hibernate都不会加载所有相关对象,而是提供占位符,一旦您尝试访问它们就会被解析.伟大的优化对吗?它是,除了你需要知道这种行为,否则你会得到神秘的错误.Google以"LazyInitializationException"为例.并且要小心表现.根据加载对象和对象图的顺序,您可能会遇到"n + 1选择问题".谷歌它提供更多信息.
架构升级
Hibernate只需重构java代码并重新启动即可轻松更改架构.你开始的时候很棒.但是你发布了第一版.除非您想失去客户,否则您需要为他们提供架构升级脚本.这意味着不再需要简单的重构,因为必须在SQL中完成所有架构更改.
视图和存储过程
Hibernate需要对其使用的数据进行独占写访问.这意味着您无法真正使用视图,存储过程和触发器,因为这些可能导致数据更改,而hibernate不知道它们.您可以让一些外部进程在单独的事务中将数据写入数据库.但是,如果这样做,您的缓存将包含无效数据.还有一件事要关心.
单线程会话
Hibernate会话是单线程的.通过会话加载的任何对象只能从同一个线程访问(包括读取).这对于服务器端应用程序是可接受的,但如果您正在执行基于GUI的应用程
我想我的观点是没有免费的饭菜.
Hibernate是一个很好的工具,但它是一个复杂的工具,它需要时间来正确理解它.如果您或您的团队成员没有这样的知识,那么单个应用程序使用纯JDBC(或Spring JDBC)可能会更简单,更快捷.另一方面,如果您愿意花时间学习它(包括通过实践和调试学习)而不是将来,您将能够更好地理解权衡.
KLE*_*KLE 12
毫无疑问,Hibernate有其复杂性.
但我真正喜欢的Hibernate方法(其他一些方法)是你可以用Java获得的概念模型更好.虽然我不认为OO是灵丹妙药,而且我没有寻找设计的理论纯度,但我发现很多次OO确实简化了我的代码.正如您专门询问的详细信息,以下是一些示例:
在增加的复杂性是不是在模型和实体,但在你的操纵所有实体,例如框架.对于维护者来说,困难的部分不是一些框架类,而是你的模型,因此Hibernate允许你将最难的部分(模型)保持在最干净的状态.
如果在所有实体中使用了字段(如id或审计字段等),则可以使用它创建超类.因此:
Hibernate还有许多功能可以处理您可能需要的其他模型特性(现在或以后,只在需要时添加它们).将其作为设计的可扩展性质量.
通过在实体之间重用(但只有适当的继承和组合),通常会有一些额外的优势.例子 :
随着时间的推移,需求不断发展.您的数据库结构存在问题.仅使用JDBC,对数据库的任何更改都必须影响代码(即双倍成本).使用Hibernate,可以通过仅更改映射而不是代码来吸收许多更改.反过来也是如此:Hibernate允许您在不更改数据库的情况下更改代码(例如版本之间)(更改映射,尽管并不总是足够).总而言之,Hibernate使您可以独立地改进数据库和代码.
出于所有这些原因,我会选择Hibernate :-)
我认为要么是一个很好的选择,但我个人会使用hibernate.我不认为hibernate对于那么大的项目来说太过分了.
Hibernate真正让我感到惊讶的是处理实体/表之间的关系.如果您同时处理修改父项和子项(孙子,兄弟姐妹等),手工执行JDBC可能会占用大量代码.Hibernate可以使这变得轻而易举(通常单个保存父实体就足够了).
然而,在处理Hibernate时肯定存在复杂性,例如理解Session刷新的工作原理以及处理延迟加载.