Java 休眠或 JDBC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1353137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:31:43  来源:igfitidea点击:

Hibernate or JDBC

javahibernatejdbc

提问by jmq

I have a thick client, java swing application with a schema of 25 tables and ~15 JInternalFrames (data entry forms for the tables). I need to make a design choice of straight JDBC or ORM (hibernate with spring framework in this case) for DBMS interaction. Build out of the application will occur in the future.

我有一个胖客户端 java swing 应用程序,其架构包含 25 个表和 ~15 个 JInternalFrames(表的数据输入表单)。我需要为 DBMS 交互做出直接 JDBC 或 ORM(在这种情况下使用 spring 框架休眠)的设计选择。应用程序的构建将在未来发生。

Would hibernate be overkill for a project of this size? An explanation of either yes or no answer would be much appreciated (or even a different approach if warranted).

对于这种规模的项目,hibernate 会不会太过分了?对是或否答案的解释将不胜感激(如果有必要,甚至可以采用不同的方法)。

TIA.

TIA。

采纳答案by Gregory Mostizky

Good question with no single simple answer.

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

I used to be a big fan of Hibernate after using it in multiple projects over multiple years. I used to believe that any project should default to hibernate.

在多年的多个项目中使用 Hibernate 后,我曾经是它的忠实粉丝。我曾经相信任何项目都应该默认休眠。

Today I am not so sure.

今天我不太确定。

Hibernate (and JPA) is great for some things, especially early in the development cycle. It is much faster to get to something working with Hibernate than it is with JDBC. You get a lot of features for free - caching, optimistic locking and so on.

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

On the other hand it has some hidden costs. Hibernate is deceivingly simple when you start. Follow some tutorial, put some annotations on your class - and you've got yourself persistence. But it's not simple and to be able to write good code in it requires good understanding of both it's internal workings and database design. If you are just starting you may not be aware of some issues that may bite you later on, so here is an incomplete list.

另一方面,它有一些隐藏的成本。当您开始时,Hibernate 非常简单。按照一些教程,在你的类上添加一些注释——你就拥有了自己的持久性。但这并不简单,并且能够在其中编写好的代码需要对它的内部工作和数据库设计有很好的理解。如果您刚刚开始,您可能不知道以后可能会困扰您的一些问题,因此这里是一个不完整的列表。

Performance

表现

The runtime performance is good enough, I have yet to see a situation where hibernate was the reason for poor performance in production. The problem is the startup performance and how it affects your unit tests time and development performance. When hibernate loads it analyzes all entities and does a lot of pre-caching - it can take about 5-10-15 seconds for a not very big application. So your 1 second unit test is going to take 11 secods now. Not fun.

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

Database Independency

数据库独立性

It is very cool as long as you don't need to do some fine tuning on the database.

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

In-memory Session

内存会话

For every transaction Hibernate will store an object in memory for every database row it "touches". It's a nice optimization when you are doing some simple data entry. If you need to process lots of objects for some reason though, it can seriously affect performance, unless you explicitly and carefully clean up the in-memory session on your own.

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

Cascades

级联

Cascades allow you to simplify working with object graphs. For example if you have a root object and some children and you save root object, you can configure hibernate to save children as well. The problem starts when your object graph grow complex. Unless you are extremely careful and have a good understanding of what goes on internally, it's easy to mess this up. And when you do it is very hard to debug those problems.

级联允许您简化对象图的使用。例如,如果您有一个根对象和一些子对象,并且您保存了根对象,那么您也可以配置 hibernate 来保存子对象。当您的对象图变得复杂时,问题就开始了。除非你非常小心并且对内部发生的事情有很好的理解,否则很容易搞砸。当你这样做时,很难调试这些问题。

Lazy Loading

延迟加载

Lazy Loading means that every time you load an object, hibernate will not load all it's related objects but instead will provide place holders which will be resolved as soon as you try to access them. Great optimization right? It is, except you need to be aware of this behaviour otherwise you will get cryptic errors. Google "LazyInitializationException" for an example. And be careful with performance. Depending on the order of how you load your objects and your object graph you may hit "n+1 selects problem". Google it for more information.

延迟加载意味着每次加载对象时,hibernate 不会加载所有与它相关的对象,而是提供占位符,一旦您尝试访问它们,这些占位符就会被解析。很棒的优化对吧?是的,除非您需要注意这种行为,否则您会遇到神秘的错误。以谷歌“LazyInitializationException”为例。并注意性能。根据您加载对象和对象图的顺序,您可能会遇到“n+1 选择问题”。谷歌它以获取更多信息。

Schema Upgrades

架构升级

Hibernate allows easy schema changes by just refactoring java code and restarting. It's great when you start. But then you release version one. And unless you want to lose your customers you need to provide them schema upgrade scripts. Which means no more simple refactoring as all schema changes must be done in SQL.

Hibernate 允许通过重构 java 代码并重新启动来轻松更改模式。当你开始时它很棒。但是随后您发布了第一个版本。除非您想失去客户,否则您需要为他们提供架构升级脚本。这意味着不再需要简单的重构,因为所有模式更改都必须在 SQL 中完成。

Views and Stored Procedures

视图和存储过程

Hibernate requires exclusive write access to the data it works with. Which means you can't really use views, stored procedures and triggers as those can cause changes to data with hibernate not aware of them. You can have some external processes writing data to the database in a separate transactions. But if you do, your cache will have invalid data. Which is one more thing to care about.

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

Single Threaded Sessions

单线程会话

Hibernate sessions are single threaded. Any object loaded through a session can only be accessed (including reading) from the same thread. This is acceptable for server side applications but might complicate things unnecessary if you are doing GUI based application.

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

I guess my point is that there are no free meals.

我想我的观点是没有免费的饭菜。

Hibernate is a good tool, but it's a complex tool, and it requires time to understand it properly. If you or your team members don't have such knowledge it might be simpler and faster to go with pure JDBC (or Spring JDBC) for a single application. On the other hand if you are willing to invest time into learning it (including learning by doing and debugging) than in the future you will be able to understand the tradeoffs better.

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

回答by cletus

Hibernate can be good but it and other JPA ORMs tend to dictate your database structure to a degree. For example, composite primary keys can be done in Hibernate/JPA but they're a little awkward. There are other examples.

Hibernate 可能很好,但它和其他 JPA ORM 往往会在一定程度上决定您的数据库结构。例如,复合主键可以在 Hibernate/JPA 中完成,但它们有点笨拙。还有其他例子。

If you're comfortable with SQL I would strongly suggest you take a look at Ibatis. It can do 90%+ of what Hibernate can but is far simpler in implementation.

如果您对 SQL 感到满意,我强烈建议您查看Ibatis。它可以完成 Hibernate 90% 以上的功能,但在实现上要简单得多。

I can't think of a single reason why I'd ever choose straight JDBC (or even Spring JDBC) over Ibatis. Hibernate is a more complex choice.

我想不出一个原因,为什么我会选择直接的 JDBC(甚至 Spring JDBC)而不是 Ibatis。Hibernate 是一个更复杂的选择。

Take a look at the Spring and Ibatis Tutorial.

查看Spring 和 Ibatis 教程

回答by Brian Yarger

I think either is a fine choice, but personally I would use hibernate. I don't think hibernate is overkill for a project of that size.

我认为两者都是不错的选择,但我个人会使用休眠。我不认为 hibernate 对于这种规模的项目来说是多余的。

Where Hibernate really shines for me is dealing with relationships between entities/tables. Doing JDBC by hand can take a lot of code if you deal with modifying parent and children (grandchildren, siblings, etc) at the same time. Hibernate can make this a breeze (often a single save of the parent entity is enough).

Hibernate 真正让我眼前一亮的是处理实体/表之间的关系。如果您同时处理修改父级和子级(孙子、兄弟姐妹等),手动执行 JDBC 可能需要大量代码。Hibernate 可以使这变得轻而易举(通常对父实体进行一次保存就足够了)。

There are certainly complexities when dealing with Hibernate though, such as understanding how the Session flushing works, and dealing with lazy loading.

但是,在处理 Hibernate 时肯定有一些复杂性,例如了解 Session 刷新的工作原理,以及处理延迟加载。

回答by topchef

Straight JDBC would fit the simplest cases at best.

直接 JDBC 最多适合最简单的情况。

If you want to stay within Java and OOD then going Hibernate or Hibernate/JPA or any-other-JPA-provider/JPA should be your choice.

如果您想留在 Java 和 OOD 中,那么选择 Hibernate 或 Hibernate/JPA 或 any-other-JPA-provider/JPA 应该是您的选择。

If you are more comfortable with SQL then having Spring for JDBC templates and other SQL-oriented frameworks won't hurt.

如果您更熟悉 SQL,那么使用 Spring for JDBC 模板和其他面向 SQL 的框架不会有什么坏处。

In contrast, besides transactional control, there is not much help from having Spring when working with JPA.

相比之下,除了事务控制之外,在使用 JPA 时使用 Spring 并没有太大帮助。

回答by KLE

No doubt Hibernate has its complexity.

毫无疑问,Hibernate 有其复杂性。

But what I really like about the Hibernate approach (some others too) is the conceptual model you can get in Java is better. Although I don't think of OO as a panacea, and I don't look for theoritical purity of the design, I found so many times that OO does in fact simplify my code. As you asked specifically for details, here are some examples :

但我真正喜欢 Hibernate 方法(还有其他一些方法)的一点是,您可以在 Java 中获得更好的概念模型。虽然我不认为 OO 是灵丹妙药,我也不追求设计的理论纯度,但我发现很多次 OO 确实简化了我的代码。正如您专门询问详细信息,以下是一些示例:

  • the added complexity is not in the modeland entities, but in your framework for manipulating all entities for example. For maintainers, the hard part is not a few framework classes but your model, so Hibernate allows you to keep the hard part (the model) at its cleanest.

  • if a field (like an id, or audit fields, etc) is used in all your entities, then you can create a superclasswith it. Therefore :

    • you write less code, but more importantly ...
    • there are less concepts in your model (the unique concept is unique in the code)
    • for free, you can write code more generic, that provided with an entity (unknown, no type-switching or cast), allows you to access the id.
  • Hibernate has also many features to deal with other model caracteristics you might need (now or later, add them only as needed). Take it as an extensibilityquality for your design.

    • You might replace inheritance (subclassing) by composition (several entities having a same member, that contains a few related fields that happen to be needed in several entities).
    • There can be inheritance between a few of your entities. It often happens that you have two tables that have pretty much the same structure (but you don't want to store all data in one table, because you would loose referential integrity to a different parent table).
  • With reuse between your entities (but only appropriate inheritance, and composition), there is usually some additional advantages to come. Examples :

    • there is often some way to read the data of the entities that is similar but different. Suppose I read the "title" field for three entities, but for some I replace the result with a differing default value if it is null. It is easy to have a signature "getActualTitle" (in a superclass or an interface), and implement the default value handling in the three implementations. That means the code out of my entities just deals with the concept of an "actual title" (I made this functional concept explicit), and the method inheritance takes care of executing the correct code (no more switch or if, no code duplication).
    • ...
  • Over time, the requirements evolve. There will be a point where your database structure has problems. With JDBC alone, any change to the database must impact the code (ie. double cost). With Hibernate, many changes can be absorbed by changing only the mapping, not the code. The same happens the other way around : Hibernate lets you change your code (between versions for example) without altering your database (changing the mapping, although it is not always sufficient). To summarize, Hibernate lets your evolve your database and your code independtly.

  • 例如,增加的复杂性不在模型和实体中,而在您用于操作所有实体的框架中。对于维护者来说,困难的部分不是几个框架类,而是你的模型,所以 Hibernate 允许你保持最困难的部分(模型)最干净。

  • 如果您的所有实体中都使用了一个字段(如 id 或审计字段等),那么您可以使用它创建一个超类。所以 :

    • 你写的代码更少,但更重要的是......
    • 您的模型中的概念较少(唯一的概念在代码中是唯一的)
    • 免费,您可以编写更通用的代码,提供实体(未知,没有类型切换或强制转换),允许您访问 id。
  • Hibernate 还具有许多功能来处理您可能需要的其他模型特征(现在或以后,仅在需要时添加它们)。将其视为设计的可扩展性质量。

    • 您可以通过组合(具有相同成员的多个实体,其中包含几个恰好在多个实体中需要的相关字段)来替换继承(子类化)。
    • 您的几个实体之间可能存在继承关系。经常发生的是,您有两个具有几乎相同结构的表(但您不想将所有数据存储在一个表中,因为您会失去对不同父表的引用完整性)。
  • 通过实体之间的重用(但只有适当的继承组合),通常会有一些额外的优势。例子 :

    • 通常有一些方法可以读取相似但不同的实体的数据。假设我读取了三个实体的“标题”字段,但对于某些实体,如果结果为空,我将其替换为不同的默认值。很容易有一个签名“getActualTitle”(在超类或接口中),并在三个实现中实现默认值处理。这意味着我的实体中的代码只处理“实际标题”的概念(我明确了这个功能概念),并且方法继承负责执行正确的代码(不再有 switch 或 if,没有代码重复) .
    • ...
  • 随着时间的推移,需求会发生变化。你的数据库结构会有问题。单独使用 JDBC,对数据库的任何更改都必须影响代码(即双倍成本)。使用 Hibernate,可以通过仅更改映射而不是代码来吸收许多更改。反过来也会发生同样的情况:Hibernate 允许您更改代码(例如在版本之间),而无需更改数据库(更改映射,尽管这并不总是足够的)。总而言之,Hibernate 可以让您独立地发展您的数据库和您的代码

For all these reasons, I would choose Hibernate :-)

由于所有这些原因,我会选择 Hibernate :-)

回答by Rob Bygrave

... In-memory Session ... LazyInitializationException ...

... 内存会话 ... LazyInitializationException ...

You could look at Ebean ORMwhich doesn't use session objects ... and where lazy loading just works. Certainly an option, not overkill, and will be simpler to understand.

您可以查看不使用会话对象的Ebean ORM......以及延迟加载的工作原理。当然是一种选择,而不是矫枉过正,而且会更容易理解。

回答by Asok B

Hibernate best suits for the middleware applications. Assume that we build a middle ware on top of the data base, The middelware is accessed by around 20 applications in that case we can have a hibernate which satisfies the requirement of all 20 applications.

Hibernate 最适合中间件应用程序。假设我们在数据库之上构建了一个中间件,该中间件被大约 20 个应用程序访问,在这种情况下,我们可以拥有一个满足所有 20 个应用程序要求的休眠。

回答by Creditto

  1. In JDBC, if we open a database connection we need to write in try, and if any exceptions occurred catch block will takers about it, and finally used to close the connections.

  2. In jdbc all exceptions are checked exceptions, so we must write code in try, catch and throws, but in hibernate we only have Un-checked exceptions

  3. Here as a programmer we must close the connection, or we may get a chance to get our of connections message…!

  4. Actually if we didn't close the connection in the finally block, then jdbc doesn't responsible to close that connection.

  5. In JDBC we need to write Sql commands in various places, after the program has created if the table structure is modified then the JDBC program doesn't work, again we need to modify and compile and re-deploy required, which is tedious.

  6. JDBC used to generate database related error codes if an exception will occurs, but java programmers are unknown about this error codes right.

  7. While we are inserting any record, if we don't have any particular table in the database, JDBC will rises an error like “View not exist”, and throws exception, but in case of hibernate, if it not found any table in the database this will create the table for us

  8. JDBC support LAZY loading and Hibernate supports Eager loading

  9. Hibernate supports Inheritance, Associations, Collections

  10. In hibernate if we save the derived class object, then its base class object will also be stored into the database, it means hibernate supporting inheritance

  11. Hibernate supports relationships like One-To-Many,One-To-One, Many-To- Many-to-Many, Many-To-One

  12. Hibernate supports caching mechanism by this, the number of round trips between an application and the database will be reduced, by using this caching technique an application performance will be increased automatically

  13. Getting pagination in hibernate is quite simple.

  14. Hibernate has capability to generate primary keys automatically while we are storing the records into database

  1. 在JDBC中,如果我们打开一个数据库连接,我们需要写在try中,如果发生任何异常,catch块会接受它,最后用来关闭连接。

  2. 在 jdbc 中所有异常都是受检异常,所以我们必须在 try、catch 和 throws 中编写代码,但在 hibernate 中我们只有未受检异常

  3. 这里作为程序员我们必须关闭连接,否则我们可能有机会获得我们的连接消息......!

  4. 实际上,如果我们没有在 finally 块中关闭连接,那么 jdbc 不负责关闭该连接。

  5. 在JDBC中我们需要在各个地方编写Sql命令,程序创建后如果修改表结构则JDBC程序不起作用,需要再次修改编译重新部署,繁琐。

  6. JDBC用于在发生异常时生成与数据库相关的错误代码,但是java程序员对这个错误代码一无所知。

  7. 当我们插入任何记录时,如果我们在数据库中没有任何特定的表,JDBC 将引发类似“视图不存在”的错误,并抛出异常,但在休眠的情况下,如果它在数据库中找不到任何表数据库这将为我们创建表

  8. JDBC 支持 LAZY 加载,Hibernate 支持 Eager 加载

  9. Hibernate 支持继承、关联、集合

  10. 在hibernate中如果我们保存了派生类对象,那么它的基类对象也会被存储到数据库中,这意味着hibernate支持继承

  11. Hibernate 支持一对多、一对一、多对多对多、多对一等关系

  12. Hibernate 通过这种方式支持缓存机制,将减少应用程序和数据库之间的往返次数,通过使用这种缓存技术,应用程序性能将自动提高

  13. 在 hibernate 中获取分页非常简单。

  14. 当我们将记录存储到数据库中时,Hibernate 能够自动生成主键

回答by Ankesh Roy

if billions of user using out app or web then in jdbc query will get executed billions of time but in hibernate query will get executed only once for any number of user most important and easy advantage of hibernate over jdbc.

如果数十亿用户使用 app 或 web,那么在 jdbc 中查询将被执行数十亿次,但在 hibernate 查询中,对于任意数量的用户,hibernate 比 jdbc 最重要和最简单的优势是只执行一次。