您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    扼杀功用的10个常见Hibernate错误(3)
    时间:2018-01-11 21:07 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    这是另一个比较普遍的错误。开发人员在耐久化一个新实体或更新现有实体后,调用EntityManager的flush办法时常常会出现这个错误。这迫使Hibernate对一切被管理的实体执行脏反省,并为一切未决的插入、更新或删除操作创立和执行SQL语句。这会减慢运用顺序,由于它阻止了Hibernate运用一些外部优化。

    Hibernate将一切被管理的实体存储在耐久性上下文中,并试图尽能够延迟写操作的执行。这允许Hibernate将同一实体上的多个更新操作兼并为一个SQL UPDATE语句,经过JDBC批处置绑定多个相反的SQL语句,并避免执行重复的SQL语句,这些SQL语句前往你已在以后Session中运用的实体。

    作为一个阅历规律,你应该避免任何对flush办法的调用。JPQL批量操作是稀有的例外之一,对此我将在错误9中解释。

    错误8:运用Hibernate应付一切

    Hibernate的对象关系映射和各种功用优化使大少数CRUD用例的完成十分复杂和高效。这使得Hibernate成为许多项目的一个很好的选择。但这并不意味着Hibernate关于一切的项目都是一个很好的处置方案。

    我在我之前的一个帖子和视频中详细讨论过这个成绩。JPA和Hibernate为大少数创立、读取或更新一些数据库记载的标准CRUD用例提供了很好的支持。关于这些用例,对象关系映射可以大大提升消费力,Hibernate的外部优化提供了一个很优越的功用。

    但是,当你需求执行十分复杂的查询、实施剖析或报告用例或对少量记载执行写操作时,结果就不同了。一切这些状况都不适宜JPA和Hibernate的查询才能以及基于实体管理的生命周期。

    假设这些用例只占运用顺序的一小部分,那么你依然可以运用Hibernate。但总的来说,你应该看看其他的框架,比如jOOQ或许Querydsl,它们更接近于SQL,并且可以避免任何对象关系映射。

    错误9:逐一更新或删除庞大的实体列表

    在你看着你的Java代码时,觉得逐一地更新或删除实体也可以接受。这就是我们看待对象的方式,对吧?

    这能够是处置Java对象的标准办法,但假设你需求更新少量的数据库记载,那么,这就不是一个好办法了。在SQL中,你只需一次定义一个影响多个记载的UPDATE或DELETE语句。数据库将会十分高效地处置这些操作。

    不幸的是,用JPA和Hibernate操作起来则没有那么容易。每个实体都有本人的生命周期,而你假设要更新或删除多个实体的话,则首先需求从数据库加载它们。然后在每个实体上执行操作,Hibernate将为每个实体生成所需的SQL UPDATE或DELETE语句。因此,Hibernate不会只用1条语句来更新1000条数据库记载,而是至少会执行1001条语句。

    很显然,执行1001条语句比仅仅执行1条语句需求破费更多的时间。幸运的是,你可以运用JPQL、原生SQL或Criteria查询对JPA和Hibernate执行相反的操作。

    但是它有一些你应该知道的反作用。在数据库中执行更新或删除操作时,将不运用实体。这提供了更佳的功用,但它同时疏忽了实体生命周期,并且Hibernate不能更新任何缓存。

    在《How to use native queries to perform bulk updates》一文中对此我有一个详细的解释。

    简而言之,在执行批量更新之前,你不应运用任何生命周期侦听器以及在EntityManager上调用flush和clear办法。flush办法将强迫Hibernate在clear办法从以后耐久化上下文中别离一实在体之前,将一切待处置的更改写入数据库。

    em.flush(); 

    em.clear(); 

    Query query = em.createQuery("UPDATE Book b SET b.price = b.price*1.1"); 

    query.executeUpdate(); 

    错误10:运用实体停止只读操作

    JPA和Hibernate支持一些不同的projections。假设你想优化你的运用顺序的功用,那么你应该运用projections。最清楚的缘由是你应该只选择用例中需求的数据。

    但这不是独一的缘由。正如我在最近的测试中显示的那样,即使你读取了相反的数据库列,DTO projections也比实体快得多。

    在SELECT子句中运用结构函数表达式而不是实体只是一个小小的改动。但在我的测试中,DTO projections比实体快40%。当然,两者比较的数值取决于你的用例,而且你也不应该经过这样一个复杂而有效的方式来提高功用。

    了解如何查找和修复Hibernate功用成绩

    正如你所看到的,一些小小的成绩都能够会减慢你的运用顺序。但幸运的是,我们可以轻松避免这些成绩并构建高功用耐久层。

    【编辑引荐】

    JPA的查询言语:JPQL的关联查询

    Hibernate 4.16.Final 发布

    Hibernate 的10个常见面试成绩及答案

    Java Hibernate 之衔接池详解

    详谈Struts+Hibernate+Spring三大框架

    (责任编辑:admin)