jdbc select语句_SELECT语句使用JDBC和Hibernate批量获取

jdbc select语句

介绍

现在,我已经介绍了HibernateINSERTUPDATEDELETE语句的批处理支持,是时候分析SELECT语句结果集的批量提取了。

JDBC ResultSet提供了一个客户端Proxy游标,用于获取当前语句的返回数据。 执行该语句后,必须将结果从数据库游标传输到客户端。 该操作可以立即执行,也可以根据需要执行。

ResultSet游标有三种类型 :

游标类型 描述
TYPE_FORWARD_ONLY 这是默认的ResultSet游标类型。 结果集只能向前移动,并且结果数据可以一次获取,也可以在迭代游标时检索。 数据库可以决定在查询开始时还是在获取时获取可用的数据。
TYPE_SCROLL_INSENSITIVE 可以向前和向后滚动结果集,并且结果数据在游标仍处于打开状态时发生的并发更改不敏感
TYPE_SCROLL_SENSITIVE 可以向前和向后滚动结果集,并且结果数据在游标仍处于打开状态时发生的并发更改敏感 。 因此,数据是按需获取的,而不是从数据库游标缓存中获取的


并非所有数据库驱动程序都实现所有游标类型,并且批处理获取行为是通过JDBC语句 fetchSize属性控制的,根据Javadoc

当此Statement生成的ResultSet对象需要更多行时,向JDBC驱动程序提供有关应从数据库中获取的行数的提示。 如果指定的值为零,则忽略提示。 默认值为零。

因此,默认的获取策略是特定于数据库的,并且从应用程序性能的角度来看,这方面在调整数据访问层时非常重要:

  • Oracle

    默认情况下,当Oracle JDBC运行查询时,它一次从数据库游标中检索到10行的结果集。根据Oracle JDBC驱动程序文档 :“合理的”取决于应用程序的详细信息。 Oracle建议fetchSize不超过100,尽管在某些情况下可能更合适。 对于某些查询,即使返回许多行, fetchSize可能也会过大。
  • MySQL

    默认情况下, 结果集是完全检索和存储在内存中。 在大多数情况下,这是最有效的操作方式,并且由于MySQL网络协议的设计,因此更易于实现。
  • SQL服务器

    通常,当用于SQL ServerMicrosoft JDBC驱动程序执行查询时,驱动程序会将所有结果从服务器检索到应用程序内存中。 尽管这种方法最大程度地减少了SQL Server上的资源消耗,但它可以在JDBC应用程序中引发产生非常大结果的查询的OutOfMemoryError
  • PostgreSQL

    默认情况下,驱动程序一次收集查询的所有结果。 这对于大型数据集可能会很不方便,因此JDBC驱动程序提供了一种将ResultSet基于数据库游标并且仅获取少量行的方法。
  • DB2

    默认情况下,驱动程序一次收集查询的所有结果。 这对于大型数据集可能会很不方便,因此JDBC驱动程序提供了一种将ResultSet基于数据库游标并且仅获取少量行的方法。 fetchSize属性不同于queryDataSize属性。 fetchSize影响返回的行数,而queryDataSize影响返回的字节数。

    例如,如果结果集大小为50 KB,而queryDataSize的值为32767(32KB),则需要两次到数据库服务器的行程才能检索结果集。 但是,如果将queryDataSize设置为65535(64 KB),则仅需要一次访问数据源即可检索结果集。

Java Persistence Query接口通过Query.getResultList()方法调用仅提供全结果检索。

Hibernate还通过其特定的Query.scroll() API支持可滚动的ResultSet游标。

可滚动的ResultSets唯一明显的优点是,由于可以按需获取数据,因此可以避免客户端的内存问题。 这听起来似乎是很自然的选择,但实际上,由于以下原因,您不应该获取大型结果集:

  • 大型结果集会占用大量数据库服务器资源,并且由于数据库是高度并发的环境 ,因此可能会妨碍可用性和可伸缩性
  • 表的大小趋于增长,适度的结果集可能很容易变成很大的表。 这种情况发生在生产系统中,很早就发布了应用程序代码。 因为用户只能浏览整个结果集中的一小部分,所以分页是一种更具可伸缩性的数据提取方法
  • 过于常见的偏移分页不适用于大型结果集(因为响应时间随页码线性增加),并且在遍历大型结果集时应考虑键集分页 。 键集分页提供了恒定的响应时间 ,对所获取页面的相对位置不敏感
  • 即使对于批处理作业 ,将处理项目限制为适当的批处理大小总是比较安全的。 大批处理可能导致内存问题或导致长时间运行的事务,从而增加了撤消/重做事务日志的大小

测试时间

我们的域实体模型如下所示:

postcommentfetchsize

以下测试将用于验证各种结果集的获取行为:

@Test
public void testFetchSize() {doInTransaction(session -> {int batchSize = batchSize();for(int i = 0; i < itemsCount(); i++) {Post post = new Post(String.format("Post no. %d", i));int j = 0;post.addComment(new Comment(String.format("Post comment %d:%d", i, j++)));post.addComment(new Comment(String.format("Post comment %d:%d", i, j++)));session.persist(post);if(i % batchSize == 0 && i > 0) {session.flush();session.clear();}}});long startNanos = System.nanoTime();LOGGER.info("Test fetch size");doInTransaction(session -> {List posts = session.createQuery("select p " +"from Post p " +"join fetch p.comments ").list();LOGGER.info("{}.fetched {} entities",getClass().getSimpleName(),posts.size());});LOGGER.info("{}.testFetch took {} millis",getClass().getSimpleName(),TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos));
}

要将Hibernate配置为使用显式Statement fetchSize ,我们需要设置以下Hibernate属性:

properties.put("hibernate.jdbc.fetch_size", fetchSize());

每个测试将插入5000个Post实体,每个实体具有2个Comment

针对商业数据库运行第一个测试,结果如下:

提取大小 持续时间[毫秒]
1个 1190
10 640
100 481
1000 459
10000 449
默认值(10) 545


提取大小越大,则提取整个结果集所需的往返行程越少。 如果返回的行包含许多列,则较大的提取大小将按比例要求较大的数据库缓冲区。

第二轮测试针对PostgreSQL 9.4运行,结果如下:

提取大小 持续时间[毫秒]
1个 1181
10 572
100 485
1000 458
10000 437
默认(全部) 396


即使fetchSize等于要返回的总行数,默认的fetch大小也会产生最佳结果。 由于没有上限缓冲区限制,因此在检索大型结果集时,默认的提取大小可能会导致OutOfMemoryError问题。

结论

虽然大多数数据库服务都不会对结果集的获取大小施加默认上限,但是最好限制整个结果集(如果要求允许的话)。 大小有限的结果集应解决无限制的获取大小缺点,同时即使在查询的数据逐渐增长的情况下,也要确保可预测的响应时间。 查询越短,行级锁的释放越快,数据访问层的可伸缩性就越高 。

  • 代码可在GitHub上获得 。

翻译自: https://www.javacodegeeks.com/2015/04/select-statements-batch-fetching-with-jdbc-and-hibernate.html

jdbc select语句

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

看懂开源项目,你得熟悉这几个 C++11 新特性

点击蓝字关注我们C11 中增加了许多的新特性。在本文中&#xff0c;我们来聊一下 lambda 表达式&#xff0c;闭包&#xff0c;std::function以及std::bind。lambda 表达式C11 中新增了 lambda 表达式这一语言特性。lambda 表达式可以让我们快速和便捷的创建一个 “函数”。下面是…

5元素升级android6,【五元素ifive X.7】无障碍升级,ifveX详细升级固件教程,快为爱机升级吧。...

android系统的乐趣就是可以随意的刷机&#xff0c;所以拿到如此高配置的ifiveX也是想随时体验最新的android系统。而很多朋友可能只会用设备&#xff0c;刷机这种比较技术性的动作就不太会弄了。也就在这周&#xff0c;才帮同事刷RUU把已经无法启动的G12刷了回来。所以刷机还是…

昆仑通态复制的程序可以用吗_昆仑通态专题(七):MCGS组态软件的设备窗口...

点击上方蓝色字体&#xff0c;关注我们设备窗口是MCGS嵌入版组态软件系统的重要组成部分&#xff0c;在设备窗口中建立系统与外部硬件设备的连接关系&#xff0c;使系统能够从外部设备读取数据并控制外部设备的工作状态&#xff0c;实现对工业过程设备的实时监控与操作。01 设备…

嵌入式C语言程序调试和宏使用的技巧

点击蓝字关注我们01.调试相关的宏在Linux使用gcc编译程序的时候&#xff0c;对于调试的语句还具有一些特殊的语法。gcc编译的过程中&#xff0c;会生成一些宏&#xff0c;可以使用这些宏分别打印当前源文件的信息&#xff0c;主要内容是当前的文件、当前运行的函数和当前的程序…

matlab中欠定方程组超定方程组_《数值天气预报》:球坐标系中的基本方程组

人们是如何预报天气的&#xff1f;目前的预报方法主要有两种&#xff1a;一种是基于由各种探测资料绘制的天气图&#xff0c;结合历史资料进行分析预测&#xff1b;另一种是基于大气方程组&#xff0c;利用数值解法对其进行求解&#xff0c;从而得到未来时刻的大气状态。后者就…

浏览器总是跳转到缓存界面_跳转到企业缓存之前要考虑的事项

浏览器总是跳转到缓存界面介绍 关系数据库事务是ACID &#xff0c;强大的一致性模型简化了应用程序开发。 由于启用Hibernate缓存是一项配置 &#xff0c;因此&#xff0c;只要数据访问层开始出现性能问题&#xff0c;就转向缓存非常吸引人。 添加缓存层确实可以提高应用程序性…

CryptoTab 服务器_如何架设FTP服务器,如何架设FTP服务器,具体架设方法

FTP服务器&#xff0c;则是在互联网上提供存储空间的计算机&#xff0c;它们依照FTP协议提供服务。 FTP的全称是File Transfer Protocol(文件传输协议)。顾名思义&#xff0c;就是专门用来传输文件的协议。简单地说&#xff0c;支持FTP协议的服务器就是FTP服务器。那么&#xf…

C语言和C++的区别和联系

点击蓝字关注我们C语言和C到底是什么关系&#xff1f;首先C和C语言本来就是两种不同的编程语言&#xff0c;但C确实是对C语言的扩充和延伸&#xff0c;并且对C语言提供后向兼容的能力。对于有些人说的C完全就包含了C语言的说法也并没有错。C一开始被本贾尼斯特劳斯特卢普&#…

hibernate语句_如何优化Hibernate EllementCollection语句

hibernate语句介绍 Hibernate支持三种数据映射类型 &#xff1a; 基本 &#xff08;例如String&#xff0c;int&#xff09;&#xff0c; Embeddable和Entity 。 通常&#xff0c;数据库行被映射到Entity &#xff0c;每个数据库列都与一个基本属性相关联。 当将多个字段映射组…

C++ 虚函数表剖析

点击蓝字关注我们一、概述为了实现C的多态&#xff0c;C使用了一种动态绑定的技术。这个技术的核心是虚函数表&#xff08;下文简称虚表&#xff09;。本文介绍虚函数表是如何实现动态绑定的。二、类的虚表每个包含了虚函数的类都包含一个虚表。我们知道&#xff0c;当一个类&a…

aix pax_通过Pax考试对JBoss Fuse 6.x进行集成测试,第一部分

aix paxJBoss Fuse是一个功能强大的分布式集成平台&#xff0c;具有内置功能&#xff0c;可用于针对集成的微服务部署进行集中式配置管理&#xff0c;服务发现&#xff0c;版本控制&#xff0c;API网关&#xff0c;负载平衡&#xff0c;故障转移等。 JBoss Fuse 6.x构建在Fabri…

android王者调不了界面,王者荣耀登录界面怎么改?登录界面更改教程[多图]

王者荣耀登录界面怎么改&#xff1f;许多玩家都想更改自己登陆的界面&#xff0c;但是都不清楚&#xff0c;下面就让安卓乐园小编为大家带来&#xff0c;登录界面更改教程。王者荣耀登录界面怎么改&#xff1f;1、安卓手机打开文件管理&#xff0c;找到根目录下Android/data/co…

y空间兑换代码_Python爬虫实战:QQ空间全自动点赞工具

QQ空间自动点赞前景提要目标确定分析介绍登陆获取cookie寻找XML寻找可变参数获取第一个空间动态寻找点赞所需的URL寻找可变参数功能提升到秒赞全部代码最后还是希望你们能给我点一波小小的关注。奉上自己诚挚的爱心私信小编01即可获取大量Python学习资料前景提要因为我周围的小…

学点 STL C++ 无序容器和元组

点击蓝字关注我们无序容器我们已经熟知了传统 C 中的有序容器 std::map/std::set&#xff0c;这些元素内部通过红黑树进行实现&#xff0c; 插入和搜索的平均复杂度均为 O(log(size))。在插入元素时候&#xff0c;会根据 < 操作符比较元素大小并判断元素是否相同&#xff0c…

html中的文档格式及举例,跟我一起从零开始学习WebAssembly(三)、最简单的例子hello world(使用自定义HTML模板)...

文章目录创建C代码片创建我们的自定义HTML模板文件编译运行实例有时我们想要使用我们自定义HTML模板。让我们来看看我们如何做到这一点。创建C代码片首先&#xff0c;创建一个名为hello2的目录。其次&#xff0c;在该目录下创建一个名为hello2.c文件。并将以下C代码保存在文件中…

设计模式适配器模式_21世纪的设计模式:适配器模式

设计模式适配器模式这是我的演讲的第三部分&#xff0c;“ 21世纪的设计模式” 。 适配器模式桥接世界。 在一个世界中&#xff0c;我们有一个概念的界面。 在另一个世界&#xff0c;我们有不同的界面。 这两个接口有不同的用途&#xff0c;但有时我们需要进行转移。 在编写良…

excel单元格斜线_掌握这20个Excel技巧,小白轻松变大神

掌握一些Excel小技巧&#xff0c;可以让你的工作效率翻倍&#xff0c;原本半个小时才能搞定的&#xff0c;现在几秒就可以轻松搞定。1、调整单元格大小选中表格&#xff0c;将光标移到表格顶部边框处&#xff0c;等其变成双向箭头即可移动。2、快速插入空行选中行&#xff0c;按…

html鼠标滚动效果代码,JS+CSS实现大气清新的滑动菜单效果代码

本文实例讲述了JSCSS实现大气清新的滑动菜单效果代码。分享给大家供大家参考&#xff0c;具体如下&#xff1a;这是一款比较大气清新的滑动导航菜单&#xff0c;CSS和JavaScript配合完成&#xff0c;鼠标放到一级菜单上&#xff0c;会滑出二级的菜单&#xff0c;兼容性也不错&a…

docker和java容器_使用Docker容器和Java EE进行持续交付

docker和java容器组织需要一种使应用程序交付快速&#xff0c;可预测和安全的方法&#xff0c;而诸如docker之类的容器所提供的敏捷性则可以帮助开发人员实现这一目标。 对于Java EE应用程序&#xff0c;这可以在容器中打包应用程序&#xff0c;应用程序服务器和其他依赖项&…

alientek ministm32液晶显示程序_佳显12864中文字库液晶专业生产液晶显示模块

GDRAM&#xff1a;(Graphic Display RAM)&#xff1a;图形显示RAM&#xff0c;这一块区域用于绘图&#xff0c;往里面写啥&#xff0c;屏幕就会显示啥&#xff0c;它与DDRAM的区别在于&#xff0c;往DDRAM中写的数据是字符的编码&#xff0c;字符的显示先是在CGROM中找到字模&a…