一尘不染

休眠或JDBC

hibernate

我有一个胖客户端,带有25个表和约15个JInternalFrames(表的数据输入表单)的架构的java
swing应用程序。我需要为DBMS交互选择直接的JDBC或ORM(在这种情况下为Spring框架hibernate)的设计选择。应用程序的构建将在将来发生。

对于这样规模的项目,hibernate会过大吗?对于是或否答案的解释将不胜感激(如果需要,甚至可以采用其他方法)。

TIA。


阅读 252

收藏
2020-06-20

共1个答案

一尘不染

好问题,没有一个简单的答案。

在多年使用多个项目之后,我曾经是Hibernate的忠实拥护者。我曾经相信任何项目都应默认为hibernate状态。

今天我不太确定。

Hibernate(和JPA)在某些方面非常有用,尤其是在开发周期的早期。使用Hibernate进行操作要比使用JDBC快得多。您可以免费获得许多功能-
缓存,乐观锁定等。

另一方面,它有一些隐性成本。 开始时,Hibernate非常简单 。遵循一些教程,在您的课程上添加一些注释-
您便会拥有持久性。但这并不简单,并且要能够编写出良好的代码,需要对它的内部工作原理和数据库设计有充分的了解。如果您只是刚开始,您可能不知道以后可能会遇到的某些问题,因此这里是不完整的列表。

性能

运行时性能足够好,我还没有看到hibernate是 生产
性能不佳的原因。问题在于启动性能以及它如何影响您的单元测试时间和开发性能。当hibernate加载时,它会分析所有实体并进行大量预缓存-
对于不太大的应用程序,可能需要5-10-15秒。因此,您的1秒钟单元测试现在将花费11秒。不好玩。

数据库独立性

只要您不需要对数据库进行一些微调,它就非常酷。

内存会议

对于每个事务,Hibernate都会为它“接触”的每个数据库行在内存中存储一​​个对象。当您进行一些简单的数据输入时,这是一个很好的优化。但是,如果由于某种原因需要处理大量对象,除非您自己明确且仔细地清理内存中的会话,否则它可能会严重影响性能。

级联

级联使您可以简化对象图的使用。例如,如果您有一个根对象和一些子对象,并且保存了根对象,则可以将hibernate配置为也保存子对象。当您的对象图变得复杂时,问题就开始了。除非您非常谨慎并且对内部发生的事情有充分的了解,否则很容易将其弄乱。而且当您这样做时,很难调试这些问题。

延迟加载

延迟加载意味着每次加载对象时,hibernate将不会加载其所有相关对象,而是会提供占位符,当您尝试访问它们时将对其进行解析。优化效果好吗?是的,除非您需要了解此行为,否则您将获得隐秘的错误。以Google“
LazyInitializationException”为例。并注意性能。根据加载对象和对象图的顺序,您可能会遇到“ n +
1选择问题”。Google以获得更多信息。

架构升级

Hibernate只需重构Java代码并重新启动,即可轻松更改架构。一开始就很棒。但是随后您发布了版本1。并且,除非您想失去客户,否则需要向他们提供架构升级脚本。这意味着不再需要简单的重构,因为所有模式更改都必须在SQL中完成。

视图和存储过程

Hibernate需要对其使用的数据具有独占写入权限。这意味着您不能真正使用视图,存储过程和触发器,因为那些视图,存储过程和触发器可能会导致hibernate状态下的数据更改而不知道它们。您可以具有一些外部流程,这些流程在单独的事务中将数据写入数据库。但是,如果这样做,您的缓存将包含无效数据。这是另外一件事。

单线程会话

hibernate会话是单线程的。通过会话加载的任何对象只能从同一线程访问(包括读取)。这对于服务器端应用程序是可以接受的,但是如果您正在基于GUI的应用程序,则可能会使不必要的事情变得复杂。

我想我的意思是 没有免费的饭菜。

Hibernate是一个很好的工具,但它是一个复杂的工具,需要时间来正确理解它。如果您或您的团队成员不了解这些知识,那么对于单个应用程序使用纯JDBC(或Spring
JDBC)可能会更简单,更快。另一方面,如果您愿意花更多的时间来学习它(包括边做边学和调试),那么将来您将能够更好地了解这些取舍。

2020-06-20