文档章节

高性能 Java 持久化的 14 个技巧

编辑部的故事
 编辑部的故事
发布于 2017/11/13 18:11
字数 2135
阅读 3844
收藏 147
点赞 4
评论 4

一个高性能的数据访问层需要大量关于数据库内部、JDBC、JPA、Hibernate的知识,本文总结了一些可用来优化企业应用程序的重要的技术。

1. SQL语句日志

如果您用了生成符合自己使用习惯的语句的框架,则应始终验证每个语句的有效性和效率。测试时使用断言机制验证更好,因为即使在提交代码之前,也可以捕获N + 1个查询问题。

2.连接管理

数据库的连接开销非常大,因此您应该始终使用连接池机制。

由于连接数由底层数据库集群的功能给出,所以您需要尽可能快地释放连接。

在性能调优中,你总是要测量、设置出正确的连接池,池的大小又是差不多的。 但像FlexyPool这样工具可以帮助您找到合适的大小,即使您已经将应用程序部署到生产环境中。

3.JDBC批处理

JDBC批处理允许我们在单个数据库往返中发送多个SQL语句。性能增益在驱动程序和数据库端都很重要。PreparedStatements 非常适合批处理,而某些数据库系统(例如 Oracle)仅支持用于预处理语句的批处理。

由于JDBC为批处理定义了独特的API(例如PreparedStatement.addBatch和PreparedStatement.executeBatch),如果您手动生成语句,那么您应该从一开始就知道是否应该使用批处理。 使用Hibernate,您可以切换到使用单个配置的批处理。

Hibernate 5.2 提供了会话级别的批处理,所以在这方面更加灵活。

4.语句缓存

语句缓存是您可以轻松利用的最鲜为人知的性能优化之一。 根据基础的JDBC驱动程序,可以在客户端(驱动程序)或数据库端(语法树甚至执行计划)上缓存PreparedStatements。

5.Hibernate 标识符

当使用Hibernate时,IDENTITY生成器不是一个好的选择,因为它禁用了JDBC批处理。

TABLE生成器更糟糕,因为它使用一个单独的事务来获取新的标识符,这会对底层事务日志以及连接池造成压力,因为每次我们需要一个新的标识符时都需要单独的连接。

SEQUENCE是正确的选择,甚至从2012版本就开始支持SQL Server。对于SEQUENCE标识符,Hibernate一直提供优化器,如 pooled 或 pooled-lo,这可以减少获取新的实体标识符值所需的数据库往返次数。

6.选择正确的列类型

您应该始终在数据库端使用正确的列类型。 列类型越紧凑,数据库工作集中可容纳的条目越多,索引将更好地适应于内存。 为此,您应该利用特定于数据库的类型(例如PostgreSQL中的IPv4地址的inet),尤其是在实现新自定义类型时,Hibernate非常灵活。

7 .关系

Hibernate 带有许多关系映射类型,但并不是所有的关系映射类型在效率上都是相等的。

应该避免单向集合和 @ManyToMany 列表。如果您确实需要使用实体集合,则首选双向 @OneToMany关联。对于 @ManyToMany 关系,使用 Set(s),因为在这种情况下它们更高效,或者简单地映射链接的多对多表,并将 @ManyToMany 关系转换为两个双向的 @OneToMany 关联。

然而,与查询不同,集合不够灵活,因为它们不易分页,这意味着当子关联的数量相当高时,我们不能使用它们。出于这个原因,你应该考虑一个集合是否真的有必要。 在许多情况下,实体查询可能是更好的选择。

8.继承

就继承而言,面向对象语言和关系数据库之间的不匹配变得更加明显。 JPA提供了SINGLE_TABLE,JOINED和TABLE_PER_CLASS来处理继承映射,每个策略都有其优缺点。

SINGLE_TABLE在SQL语句方面表现最好,但由于我们不能使用NOT NULL约束,所以我们在数据完整性方面失败了。

当同时提供更复杂的语句时,JOINED采用数据完整性限制。 只要你不使用基本类型的多态查询或@OneToMany关联,这个策略就没有问题。 它的真正的作用在于对数据访问层上由策略模式支持的多态@ManyToOne关联。

应该避免使用TABLE_PER_CLASS,因为它不会生成有效的SQL语句。

9.持久性上下文的大小

在使用 JPA 和 Hibernate 时,应该始终关注持久性上下文的大小。 出于这个原因,您不应该过多地使用托管实体。 通过限制托管实体的数量,我们可以获得更好的内存管理,并且默认的检查机制也将更加高效。

10.只抓取必要的东西

获取太多的数据可能是导致数据访问层性能出问题的首要原因。 一个问题是,即使是只读的 Projections,实体查询也是专用的。

DTO projections更适合于获取自定义视图,而实体只能在业务流需要修改时才能获取。

EAGER抓取是最糟糕的,您应该避免反模式(Anti-Pattern),例如 Open-Session in View

11.高速缓存

关系数据库系统使用许多内存缓冲区结构来避免磁盘访问。 数据库缓存经常被忽视。 我们可以通过适当调整数据库引擎来显着降低响应时间,以便工作集驻留在内存中,而不是一直从磁盘中获取。

应用程序级缓存对于许多企业应用程序来说是不可选的。 应用程序级缓存可以减少响应时间,同时为数据库关闭以进行维护或由于某些严重系统故障提供只读辅助存储库。

二级缓存对于减少读写事务响应时间非常有用,特别是在主从复制体系结构中。 根据应用程序的要求,Hibernate允许你在READ_ONLYNONSTRICT_READ_WRITEREAD_WRITETRANSACTIONAL之间进行选择。

12.并发控制

在性能和数据完整性方面,事务隔离级别的选择是非常重要的。 对于多请求Web流程,为避免丢失更新,您应该对分离的实体或 EXTENDED 持久性上下文使用 optimistic 锁定。

为避免optimistic locking误报,您可以使用无版本 optimistic 并发控制或基于读写的属性集来拆分实体。

13.释放数据库查询功能

仅仅因为您使用JPA或Hibernate,并不意味着您不应该使用原生查询。 您应该利用窗口函数,CTE(公用表表达式),CONNECT BY,PIVOT 查询。

这些构造允许您避免获取太多的数据,以便稍后在应用程序层进行转换。 如果可以让数据库进行处理,那么只能获取最终结果,因此可以节省大量的磁盘I / O和网络开销。 为避免主节点重载,可以使用数据库复制和拥有多个从属节点,这样数据密集型的任务就会在从属节点而不是主节点上执行。

14.横向扩展和纵向扩展

关系数据库的伸缩性非常好。如果Facebook、Twitter、Pinterest或StackOverflow可以扩展他们的数据库系统,那么很有可能您可以将企业应用程序扩展到其特定的业务需求。

数据库复制和分片是提高吞吐量的很好的方法,您应该完全可以利用这些经过测试的架构模式来扩展您的企业应用程序。

结论

高性能数据访问层必须与底层数据库系统互相响应。 了解关系数据库和正在使用的数据访问框架的内部工作原理可以使企业高性能应用程序和几乎没有crawls的应用程序之间产生差异。

原文:https://vladmihalcea.com/2016/06/28/14-high-performance-java-persistence-tips/

© 著作权归作者所有

共有 人打赏支持
编辑部的故事

编辑部的故事

粉丝 1106
博文 241
码字总数 400552
作品 0
深圳
运营/编辑
加载中

评论(4)

MGL_ONE
MGL_ONE
good
AkataMoKa
AkataMoKa
9.持久性上下文的大小
里面提到的“托管实体”,是什么东西?
g
gm100861
hibernate软文
神之音
神之音
涉及hibernate的偏多~
Hibernate.Everything data

Hibernate.Everything data Hibernate ORM:关系数据库域模型持久化 Hibernate Search:全文检索域模型 Hibernate Validator:基于域模型注解约束 Hibernate OGM:Nosql数据库域模型持久化 Hibe...

Rksi5
2014/10/09
0
0
编写高性能 Java 代码的最佳实践

摘要:本文首先介绍了负载测试、基于APM工具的应用程序和服务器监控,随后介绍了编写高性能Java代码的一些最佳实践。最后研究了JVM特定的调优技巧、数据库端的优化和架构方面的调整。以下是译...

这篇文章
06/20
0
0
程序运行时,对象是怎么进行放置的呢?特别是内存是怎么分配的呢?对这些方面的了解会对你有很大的帮...

1)寄存器. 这是很宽的存储区,因为它位于不同于其他存储区的地方----处理器内部.但是寄存器的数量汲取有限,所以寄存器根据需求进行分配.你不能直接控制,也不能在程序中感觉到寄存器的存在的任...

深山
2012/11/23
0
0
提示你Hibernate4开发能力的17个技巧

设计细颗粒度的持久类并且使用<component>来实现映射。 例如使用一个Address持久类来封装 street, suburb, state, postcode. 这将有利于代码重用和简化代码重构(refactoring)的工作。 对持久...

chromeplugin
2012/08/14
0
0
提升你Hibernate4开发能力的17个技巧

设计细颗粒度的持久类并且使用<component>来实现映射。 例如使用一个Address持久类来封装 street, suburb, state, postcode. 这将有利于代码重用和简化代码重构(refactoring)的工作。 对持久...

justjavac
2012/08/10
0
3
spark 使用中会遇到的一些问题及解决思路

7 内存溢出问题 在Spark中使用hql方法执行hive语句时,由于其在查询过程中调用的是Hive的获取元数据信息、SQL解析,并且使用Cglib等进行序列化反序列化,中间可能产生较多的class文件,导致J...

hblt-j
2017/11/06
0
0
Spring笔记8---数据库持久化

聊聊持久化。 ------------------------Spring的平台无关持久化异常 下面是Spring提供的数据访问模板,分别适用于不同的持久化机制 模板类org.springframework.* 用途 jca.cci.core.CciTemp...

强子哥哥
2015/01/12
0
0
Java开发每日复盘2018_0511

今天主要跟大家来分享一下「MyBatis的使用」 一句话概括: 「MyBatis」,是一种介于Java对象与数据库(MySql等)之间的用于持久化存储的框架。 使用「MyBatis」好处: 可以更高效的,基于该框...

ZeroOSTalk
05/13
0
0
Java程序员面试大纲—错过了金三银四,你还要错过2018吗?

跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽。切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己...

java高级架构牛人
04/27
0
0
图形化Hibernate框架理解

基于Hibernate框架原理的图形化理解示意图: 图解Hibernate说明: 在Hibernate工作的原理中,它是通过利用数据库以其他的配置如Hibernate.propertie、XML.mapping等来为应用程序(Applicati...

鲁雯雪
2013/12/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring基础

Spring是什么? Spring是一个开源框架,最早由Rod Johnson创建,它解决的是业务逻辑层和其他各层的松耦合问题。 经过十几年的发展,Spring正在扩展其他的领域,如:移动开发、社交API集成、N...

这很耳东先生
8分钟前
0
0
面试系列-40个Java多线程问题总结

前言 这篇文章主要是对多线程的问题进行总结的,因此罗列了40个多线程的问题。 这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也...

Ryan-瑞恩
21分钟前
0
0
微信分享的细节

分享的缩略图要求: 一、图片大小小于32k 二、图片的尺寸为 宽度 :128px 高度:128px 分享title 和 description 出现金额等 以上情况存在会导致触发分享按钮 但是页面没有反应...

Js_Mei
27分钟前
0
0
【2018.07.23学习笔记】【linux高级知识 Shell脚本编程练习】

1、编写shell脚本,计算1-100的和; #!/bin/bashsum=0for i in `seq 1 100`do sum=$[$sum+$i]doneecho $sum 2、编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求...

lgsxp
30分钟前
0
0
xss攻防浅谈

导读 XSS (Cross-Site Script) 攻击又叫跨站脚本攻击, 本质是一种注入攻击. 其原理, 简单的说就是利用各种手段把恶意代码添加到网页中, 并让受害者执行这段脚本. XSS能做用户使用浏览器能做的...

吴伟祥
30分钟前
0
0
js回调的一次应用

function hideBtn(option) { if (option == 1) { $("#addBtn").hide(); $("#addSonBtn").hide(); }}$("body").on("click", "#selectBtn", function () {......

晨猫
36分钟前
0
0
C++_读写ini配置文件

1.WritePrivateProfileString:写配置文件 WritePrivateProfileString 函数的定义形式为: BOOL WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTST......

一个小妞
36分钟前
0
0
通往阿里,BAT的50+经典Java面试题及答案解析(上)

Java是一个支持并发、基于类和面向对象的计算机编程语言。下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改。 代码复用。 增强代码的可靠性和灵活性。 增加代码的可理解性...

Java大蜗牛
36分钟前
1
0
数据库两大神器【索引和锁】

前言 只有光头才能变强 索引和锁在数据库中可以说是非常重要的知识点了,在面试中也会经常会被问到的。 本文力求简单讲清每个知识点,希望大家看完能有所收获 声明:如果没有说明具体的数据库...

Java3y
40分钟前
0
0
Application Express安装

Application Express安装文档 数据库选择和安装 数据库选择 Oracle建议直接12.2.0.1.0及以上的版本,12.1存在20618595bug(具体可参见官方文档) Oracle 12c 中安装oracle application expr...

youfen
52分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部