繁体   English   中英

JPA本地查询与“纯” JPA持久性

[英]JPA Native Queries versus 'pure' JPA persistence

我有一种情况,在这种情况下,我需要保留所有到应用程序的传入文件(平面,xml)的日志。 除了故障调查或监管目的之类的东西以外,几乎不使用此日志表,并且将定期清除数据。

我们将JPA 2.0用于持久性。 我们使用entityManager.persist();尝试了具有纯JPA持久性的初始原型entityManager.persist(); 并立即flush 但性能达不到预期。 因此,我建议对此操作使用NativeNamedQueries ,并且在测试中,性能改进非常大(300毫秒对47毫秒)。

但是首席工程师对使用NativeNamedQueries持坚决态度,他说它与数据库耦合并且难以维护。

问题:

  1. 如果必须做出决定,您对此有何看法。 应用程序投入生产后,数据库或架构更改多久发生一次?

  2. 还有其他提高性能的方法吗? 性能对于此应用程序非常重要。

自从我开始编程以来只有4年,但从未见过现有应用程序发生数据库模式更改或数据库提供程序更改的情况。

注意:我们正在使用EclipseLink 2.3和Oracle。 这也是我们正在开发的全新应用程序。 以防万一这些观点使问题更加清楚

应用程序投入生产后,数据库或架构更改多久发生一次?

这对您眼前的问题无关紧要。 对数据库模式的更改数量无关紧要。 重要的是数据库模型的可维护性,设计的良好程度。 如果尚未进行足够的性能测试,大多数商务应用程序将看到很多更改,这对大多数应用程序而言都是可悲的。

如果您正在编写典型的业务应用程序,那么我期望对象模型和数据库模型之间的某种形式的往返工程会在开发中发生。 您的DBA应该很好地拥有和了解数据库模型,以便他们可以帮助或执行由ORM框架发出的查询的微调。 请记住,您可能不仅仅依赖ORM框架发出的查询。 所有更改最好都应在开发和集成测试(如果有的话,可能是UAT)环境中进行并进行测试,然后再推广到生产环境,并且按照常识建议,所有更改都将在版本控制下进行。

在将查询耦合到数据库这一主题上,这就是您的业务必须做出的决定。 如果您要支持多个数据库,那么应该对所有数据库进行测试。 同样,您应该能够提供不同的发行版来支持不同的数据库; 这是,如果你把你的本机查询数据库中的特定变得容易orm.xml的文件一样orm-oracle.xmlorm-mysql.xml等,并重新命名文件orm.xml您准备分发之前。 使用Maven或Ant将使建议的更改易于实现。

还有其他提高性能的方法吗? 性能对于此应用程序非常重要。

那将取决于您对对象和数据模型的设计程度,对ORM框架的理解程度以及您“破坏”对象模型的意愿。

对任何应用程序进行性能调整的第一步是始终进行两次测量,然后切割一次。 您不能简单地遍历可能的解决方案列表,然后尝试每个解决方案,而又不知道它们的工作方式以及在什么情况下有用。 好的,如果您的企业愿意为此花费时间,则可以这样做,但是通常并非如此。

首先,你需要明白,为什么本地查询提供或出现*提供更好的性能。 也许这与您仅插入数据有很大关系,对于ORM框架而言,只发出INSERT语句而不是从HQL或幕后使用的抽象查询符号构造一个语句会更好。 只有分析器才能显示出差异。

如果上述内容正确,那么您可以重新考虑是否必须由ORM框架管理审核表。 如果您的应用程序仅负责写入这些表而不读取它们(并且很有可能另一个应用程序负责读取条目),那么我可能会怀疑,不对ORM中的这些表进行管理会提供更好的性能,尤其是如果使用普通JDBC发出INSERT语句。 原因很简单-如果您的ORM框架正在管理实体,则它还负责管理持久性上下文(现在包括类和关联的表); 如果没有让ORM管理实体,则可能会导致根本不需要为审核条目更新持久性上下文的情况。

您可以采取其他性能调整措施来实现健康的可能性,但是正如我之前所述,它需要您了解分析器报告并估算哪些可能的选择对您的应用程序更好。

*恐怕除非您发布基准以及如何进行基准测试,否则我将对索赔表示怀疑。

  1. 这是相当罕见的,你实际切换数据库供应商,尤其是一旦你支付牌照的几个100K的像甲骨文的优秀和高高性能数据库。 此外, INSERT语句的SQL语法变体没有那么明显,以至于您即使在使用本机SQL的情况下也无法切换数据库。

  2. 我不明白为什么修补需要额外调整的单个查询是不好的。 询问您的首席开发人员为什么他这么严格。 但是,在执行此操作之前,请使用探查器(例如JProfiler或Yourkit)来确定导致性能问题的确切位置。 使用JPA,以下任何一种都可能引起问题:缓存,急需加载相关数据(可能不需要),SQL生成效率低下,Oracle数据库中的查询执行计划不正确等,等等。毕竟不需要本地查询。

  3. 如果性能至关重要,那么JPA可能不足以胜任这项工作。 您(和您的首席开发人员)是否考虑过其他框架,例如jOOQQueryDSLMyBatis或类似的框架? 我从您的评论中了解到,您的主要用例是OLAP查询,而不是OLTP,因此,您甚至可能希望使用jOOQ具有本机支持的高级Oracle功能(例如分析功能和数据仓库功能)来例如...

1)在10年中,我仅看到2个应用程序从oracle迁移到MySQL(以节省许可成本),因此这种情况很少发生,但是如果要使用另一个数据库(例如hsqldb)编写集成测试,会遇到麻烦的。

关于应用程序投入生产后架构更改的频率,我的答案是:很多! 如果应用程序将定期更新,则可以期望很多更改,因为通常团队会更好地了解业务。 我什至参与了一个项目,在该项目中,应用程序上线一年后,架构有很大不同。

同时,这看起来像您将优化推迟到了最后一个可能的时间(这是一件好事),现在您需要使用一些本机查询(这也很经常发生)来优化sql ...我正在尝试可以说你的想法对我来说一点都不坏。

2)过去,在类似情况下(如果要检查iBatis),我曾将Hibernate和iBatis(或现在的mybatis)混合使用。 还有一个问题,为什么在每个persist()之后执行flush()? 您实际上不需要这样做。

另外,我很惊讶如果在EclipseLink中完成插入会花费更长的时间。 对persist()的调用应该花费与本地查询几乎相同的时间(我假设如果存在任何生命周期回调,它们将花费更长的时间)。 我假设您已经看过eclipseLink生成的sql,有什么不同吗?

我知道我的回答根本不是很具体,但希望能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM