Ibatis之RowHandler
当用Ibatis进行大数据量Sql查询时(如上百万条,千万条数据),如果按照一般的编程方式(如QueryForList方法)把数据查询出来再做操作则很可能会出现性能问题,如: 1.对JVM内存的大量消耗; 2.大量对象的密集创建对GC带来一定的压力; 3.数据查询和后续的数
当用Ibatis进行大数据量Sql查询时(如上百万条,千万条数据),如果按照一般的编程方式(如QueryForList方法)把数据查询出来再做操作则很可能会出现性能问题,如:
1.对JVM内存的大量消耗;
2.大量对象的密集创建对GC带来一定的压力;
3.数据查询和后续的数据操作无法并行执行等
为应对这样的场景,Ibatis提供了RowHandler接口,以回调的方式,允许用户对查询结果集进行自定义的处理,用户通过自定义实现handleRow方法一次处理一条数据,从而提高框架的灵活性。
1 2 3 4 5 6 7 8 9 10 11 |
|
* This method will be called for each row in a result set. For each row the result map * will be applied to build the value object, which is then passed in as the valueObject * parameter. * * @param valueObject The object representing a single row from the query. * @see com.ibatis.sqlmap.client.SqlMapSession */ void handleRow(Object valueObject); }
简单举例来说RowHandler的作用:
在大数据量的场景下,如:银行每天对账户的“计提”操作,如果有一千万个账户,则需要查询出一千万条账号,然后做一千万次更新(如果可以用addbatch那就肯定不用一千万次了)。为了尽可能提升性能:
1.必须防止对象爆发式的创建,因为爆发式创建会让内存急剧上升,如果没有很好的设计,还会导致对象爆发式的销毁(即:对最后一条数据处理完才会让所有对象失效,而在进行这一千万次更新期间这些内存都是被占用的)。通过自定义RowHandler,可以对数据逐条进行处理,在handleRow方法中执行更新操作,更新完之后立刻释放对象,这样便对操作进行了“离散化”,降低了对内存的占用。
2.上面通过“离散化”解决了内存占用的问题,但查询和数据处理的总时间是没有减少的,为了达到更高的效率,还需要进行“异步化”处理。在handleRow方法中,将valueObject发送到异步队列中,让查询和执行进行并行处理,进而降低总时间。其实总时间的降低体现出的只是一个优点,还有一个优点就是:进行“异步化”之后的查询时间和直接调用QueryForList的查询时间相差不会太大,查询完之后就快速释放连接了,减轻了数据库的压力。
注意事项:
当应用RowHandler时,可能仍然会发现内存急剧上升,这是因为底层JDBC返回的ResultMap仍然会一次性把数据全部返回的缘故。通过设置fetchsize可以解决这一问题,fetchsize是JDBC提供的一个配置变量,JDBC驱动按照该变量的配置值从数据库中循环取数据,而不是一次性load到内存中,这样便允许用户根据自己的实际情况做最优的参数设置,ibatis的select标签将此属性暴露了出来,可以针对某个特定的语句做独立的设置,以达到最优的性能。但是fetchsize也不能太小,否则会带来java和数据库之间频繁的交互,内存问题倒是解决了,但是频繁交互带来的性能问题又出现了,所以fetchsize的值需要以具体场景和实验数据为依据进行灵活设置。
关于fetchsize的几个链接:
http://www.2cto.com/database/201305/209625.html
http://www.java3z.com/cwbwebhome/article/article8/828.html?id=2244
http://www.smithfox.com/?e=153
http://stackoverflow.com/questions/3870500/ibatis-querywithrowhandler-still-seems-to-fetch-all-rows
http://docs.aws.amazon.com/redshift/latest/dg/jdbc-fetch-size-parameter.html
利用rowhandler还可以实现对象关联关系的创建,解决“N+1 Select“的问题,此处不详述,备忘一下,详见《Ibatis in Action》一书的相关章节。
rowhandler可以做的事情其实很多,它是一种公用的机制,只是经常被用来解决效率问题,当Ibatis框架不能满足我们的需求时,可以考虑发挥该接口的作用。
至于性能,本文说的都是偏理论的、一般性的场景,具体的解决方案需要因场景而异,经验结合需求才能得到最好的设计。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

iBatis与MyBatis:你应该选择哪个?简介:随着Java语言的快速发展,许多持久化框架也应运而生。iBatis和MyBatis是两个备受欢迎的持久化框架,它们都提供了一种简单而高效的数据访问解决方案。本文将介绍iBatis和MyBatis的特点和优势,并给出一些具体的代码示例,帮助你选择合适的框架。iBatis简介:iBatis是一个开源的持久化框架

iBatis和MyBatis:区别和优势解析导语:在Java开发中,持久化是一个常见的需求,而iBatis和MyBatis是两个广泛使用的持久化框架。虽然它们有很多相似之处,但也有一些关键的区别和优势。本文将通过详细分析这两个框架的特性、用法和示例代码,为读者提供更全面的了解。一、iBatis特性:iBatis是目前较为老旧的持久化框架,它使用SQL映射文件

ibatis和mybatis的区别:1、基本信息不同;2、开发时间不同;3、功能与易用性;4、配置文件;5、入参类型与出参类型;6、返回结果集接受方式;7、语法差异;8、数据库方言支持;9、插件支持;10、社区活跃度;11、全球化支持。详细介绍:1、基本信息不同,iBatis提供持久层框架,包括SQL Maps和Data Access Objects等等。

iBatis和MyBatis是两种主流的ORM(Object-RelationalMapping)框架,它们在设计和使用上有着许多相似之处,也存在一些细微的差别。本文将详细比较iBatis和MyBatis的异同,并通过具体的代码示例来说明它们的特点。一、iBatis与MyBatis的历史和背景iBatis是ApacheSoftwareFoundat

iBatis和MyBatis:从历史到现状的评估与对比引言:随着软件开发领域的快速发展,对于数据库访问框架也提出了越来越高的要求。iBatis和MyBatis是两个备受关注的Java持久层框架,它们都提供了一种简单灵活的方式来访问关系型数据库。本文将对这两个框架进行历史回顾,并对它们的现状进行评估与对比。一、历史回顾iBatisiBatis是由Clinton

Python是一种多功能的编程语言,在数据分析和机器学习领域广受欢迎。其简洁性、可读性和丰富的库使其成为处理复杂数据任务的理想选择。其中一个强大的应用是RFM分析,这是一种在营销中根据客户购买行为进行分割的技术。在本教程中,我们将通过使用Python来实施RFM分析的过程来指导您。我们将从解释RFM分析的概念及其在营销中的重要性开始。然后,我们将逐步深入探讨使用Python进行RFM分析的实际方面。在文章的下一部分中,我们将演示如何使用Python为每个客户计算RFM分数,考虑到为最近性、频率和

近日,《黑神话:悟空》在全球范围内都引发了巨大的关注,各平台的同时在线人数都再创新高,这款游戏在多个平台取得了巨大的商业成功。《黑神话:悟空》的Xbox版延期虽然《黑神话:悟空》已于PC和PS5平台发布,但其Xbox版一直没有确切消息。据了解,官方已确认《黑神话:悟空》将登陆Xbox平台。但具体上线日期尚未公布。最近有消息称,Xbox版的延期是由于技术问题所致。据相关博主透露,他在Gamescom期间与开发人员和"Xbox内部人士"的交流中得知,《黑神话:悟空》的Xbox版存

ibatis mysql乱码的解决办法:1、检查mysql的字符集,并设置为utf8;2、将配置修改为“<property name="url"><value><![CDATA[jdbc:mysql://localhost:3306/yourDbNameuseUnicode=TRUE&characterEncoding=utf8]]></value>”即可。
