Spring+Hibernate处理大批量数据

对象打包成List

      关于使用Spring+Hibernate进行大批量数据的插入和更新,它的性能和使用JDBC PreparedStatement的batch批量操作以及数据库的存储过程操作几乎可以一样高。在Hibernate的官方文档里说到了Batchprocessing。Spring+Hibernate大批量处理数据想要说明如何使用Hibernate大批量处理数据获得高性能。

使用Hibernate将 100 000 条记录插入到数据库的一个很自然的做法可能是这样的

Session session = sessionFactory.openSession();  Transaction tx = session.beginTransaction();  for ( int i=0; i<100000; i++ ) {      Customer customer = new Customer(.....);      session.save(customer);  }  tx.commit();  session.close();

这段程序大概运行到 50 000条记录左右会失败并抛出 内存溢出异常(OutOfMemoryException) 。这是因为 Hibernate 把所有新插入的 客户(Customer)实例在session级别的缓存区进行了缓存的缘故。

我们会在本章告诉你如何避免此类问题。首先,如果你要执行批量处理并且想要达到一个理想的性能,那么使用JDBC的批量(batching)功能是至关重要。将JDBC的批量抓取数量(batch size)参数设置到一个合适值(比如,10-50之间):

hibernate.jdbc.batch_size 20

你也可能想在执行批量处理时关闭二级缓存:

hibernate.cache.use_second_level_cache false

14.1. 批量插入(Batch inserts)

如果要将很多对象持久化,你必须通过经常的调用 flush() 以及稍后调用 clear() 来控制第一级缓存的大小。

Session session = sessionFactory.openSession();  Transaction tx = session.beginTransaction();       for ( int i=0; i<100000; i++ ) {      Customer customer = new Customer(.....);      session.save(customer);      if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同          //flush a batch of inserts and release memory:          //将本批插入的对象立即写入数据库并释放内存          session.flush();          session.clear();      }  }       tx.commit();  session.close();

14.2. 批量更新(Batch updates)

此方法同样适用于检索和更新数据。此外,在进行会返回很多行数据的查询时,你需要使用 scroll() 方法以便充分利用服务器端游标所带来的好处。

Session session = sessionFactory.openSession();  Transaction tx = session.beginTransaction();       ScrollableResults customers = session.getNamedQuery("GetCustomers")      .setCacheMode(CacheMode.IGNORE)      .scroll(ScrollMode.FORWARD_ONLY);  int count=0;  while ( customers.next() ) {      Customer customer = (Customer) customers.get(0);      customer.updateStuff(...);      if ( ++count % 20 == 0 ) {          //flush a batch of updates and release memory:          session.flush();          session.clear();      }  }       tx.commit();  session.close();

14.3. 大批量更新/删除(Bulk update/delete)

就像已经讨论的那样,自动和透明的 对象/关系 映射(object/relational mapping)关注于管理对象的状态。这就意味着对象的状态存在于内存,因此直接更新或者删除 (使用 SQL语句 UPDATE 和 DELETE)数据库中的数据将不会影响内存中的对象状态和对象数据。 不过,Hibernate提供通过Hibernate查询语言(第 15 章 HQL:Hibernate查询语言)来执行大批量SQL风格的(UPDATE)和(DELETE) 语句的方法。

UPDATE 和 DELETE语句的语法为: (UPDATE | DELETE ) FROM? ClassName (WHERE WHERE_CONDITIONS)?。有几点说明:

  • 在FROM子句(from-clause)中,FROM关键字是可选的

  • 在FROM子句(from-clause)中只能有一个类名,并且它不能有别名

  • 不能在大批量HQL语句中使用连接(显式或者隐式的都不行)。不过在WHERE子句中可以使用子查询。

  • 整个WHERE子句是可选的。

举个例子,使用Query.executeUpdate()方法执行一个HQL UPDATE语句:

Session session = sessionFactory.openSession();          Transaction tx = session.beginTransaction();            String hqlUpdate = "update Customer set name = :newName where name = :oldName";          int updatedEntities = s.createQuery( hqlUpdate )                              .setString( "newName", newName )                              .setString( "oldName", oldName )                              .executeUpdate();          tx.commit();          session.close();

执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法(此方法是为那些熟悉JDBCPreparedStatement.executeUpdate() 的人们而设定的)

Session session = sessionFactory.openSession();          Transaction tx = session.beginTransaction();            String hqlDelete = "delete Customer where name = :oldName";          int deletedEntities = s.createQuery( hqlDelete )                              .setString( "oldName", oldName )                              .executeUpdate();          tx.commit();          session.close();

由Query.executeUpdate()方法返回的整型值表明了受此操作影响的记录数量。注意这个数值可能与数据库中被(最后一条SQL语句)影响了的“行”数有关,也可能没有。一个大批量HQL操作可能导致多条实际的SQL语句被执行,举个例子,对joined-subclass映射方式的类进行的此类操作。这个返回值代表了实际被语句影响了的记录数量。在那个joined-subclass的例子中,对一个子类的删除实际上可能不仅仅会删除子类映射到的表而且会影响“根”表,还有可能影响与之有继承关系的joined-subclass映射方式的子类的表。

注意,上述大批量HQL操作的少数限制会在新版本中得到改进;进一步详细信息请参考JIRA里的路线图

相关推荐

JVM优化方案

堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。典型设置:java -Xmx3550m -Xms355

ye1992的专栏 69

org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /otter/channel/6/

HTTP ERROR 500Problem accessing /channelList.htm. Reason:Failed to invoke Valve[#2/3, level 3]: com.alibaba.citrus.turbine.pipeline.valve.PerformTemplateScreenValve#14366f3:PerformTemplateScreen

ye1992的专栏 7819

react-native-barcodescanner扫码第二次进去黑屏

react-native(react-native-barcodescanner)扫码第一次进去的时候正常但是之后出现黑屏,在网上的说是新场景要pop掉(可能是我的版本和网上的版本不一样导致的),但是我pop掉了第二次进去还是黑屏,纠结了很久,猜测是调用了摄像头没有释放掉导致的,无奈只能动barcodescanner的源码了,看了该项目中的文件目录如下:期间修改过这三个文件很多其他的位

ye1992的专栏 2284

ubuntu下nginx安装手记

Nginx是一个高性能的HTTP和反向代理服务器.Nginx 使用 Unix 下常用的 './configure && make && make install' 过程来编译安装.configure 脚本确定系统所具有一些特性,特别是 nginx 用来处理连接的方法。然后,它创建 Makefile 文件。官网:http://nginx.org/下载页面:http:/

ye1992的专栏 839

linux ubuntu 的桌面怎样关闭

命令行模式(ctrl+alt+F2),执行一下 命令sudo /etc/init.d/lightdm stop (关闭窗口);sudo /etc/init.d/lightdm restart (重启窗口)

ye1992的专栏 6856

linux iptables开放端口命令

#/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT#/sbin/iptables -I INPUT -p tcp --dport 22 -j ACCEPT#/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT然后保存:#/etc/rc.d/init.d/iptables sa

ye1992的专栏 7785

微信支付有汉字时出现签名错误的解决办法

最近发现在win2003/win2008开发微信支付时,有汉字时出现签名错误,但在win7上不会出错,最后发现是字符编码不一致造成的。解决办法改正wxpay-scanpay-java-sdk-1.0.jar中的md5.java文件,/**     * MD5编码     * @param origin 原始字符串     * @return 经过MD5加密之后的

ye1992的专栏 2037

SpringMVC+MyBatis+logback

目前主流的Web MVC框架,除了Struts这个主力 外,还有Spring MVC,主要是由于Spring MVC配置比较简单,使用起来也十分明了,非常灵活,与Spring 集成较好,对RESTful API的支持也比struts要好。MyBatis是ibatis的升级版,作为hibernate的老对手,它 是一个可以自定义SQL、存储过程和高级映射的持久层框架。与hibernate的主

ye1992的专栏 4242

使用logback.xml配置来实现日志文件输出

Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4

ye1992的专栏 1万+

当spring 容器初始化完成后执行某个方法

在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查。比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出哪个文件的xml文件使用了这个函数。而在Spring的web项目中,我们可以介入Spring的启动过程。我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,这个时候我

ye1992的专栏 1万+

当在mybatis用到foreach的时候,会报这个错误Parameter '__frch_item_0' not found. Available parameters are [list]会出现的

异常信息Caused by: org.apache.ibatis.binding.BindingException: Parameter '__frch_item_0' not found. Available parameters are [list]at org.apache.ibatis.session.defaults.DefaultSqlS

ye1992的专栏 8365

Nginx负载均衡+监控状态检测

Nginx负载均衡与可用性检查在业界,一直流传这样一句话:Nginx抗并发能力强!为什么Nginx抗并发能力强?原因是使用了非阻塞、异步传输阻塞:如apache代理tomcat时,apache开启10个进程,同时处理着10个请求,在tomcat没有返回给apache结果时,apache是不会处理用户发出的第11个请求非阻塞:如nginx代理tomcat时,nginx开启1000个并

ye1992的专栏 1万+

js将long日期格式转换为标准日期格式

"javascript">         //扩展Date的format方法       Date.prototype.format = function (format) {          var o = {              "M+": this.getMonth() + 1,              "d+": this.getDate(),     

ye1992的专栏 6588

Quartz时间配置规则

一个Cron-表达式是一个由六至七个字段组成由空格分隔的字符串,其中6个字段是必须的而一个是可选的,如下: 字段名允许的值允许的特殊字符 秒     0-59        , - * /分     0-59         , - * /小时    0-23         , - * /日     1-31         , - * ? / L W C

ye1992的专栏 1621

SVN设置强制提交者填写注释信息,svn版本管理工具为VisualSVN Server 2.5.8

环境简述:SVN服务器:WindowsSVN版本:VisualSVN Server 2.5.8操作方法:在SVN的Repositories下,找到要配置的项目,在项目目录下找到hooks文件夹,在其下创建pre-commit.bat文件,把下面复制进去就可以了(无需重启,如果改动,保存bat文件,配置就生效):================= bat文件内容 开始====

ye1992的专栏 2209

Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解

引言:接上一篇文章,对@RequestMapping进行地址映射讲解之后,该篇主要讲解request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用;简介:handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)A、处理requet uri 部分(这里指ur

ye1992的专栏 1541

基于RHEL 6.5安装Oracle 11g详细教程(4)安装Oracle前的准备

4  安装Oracle前的准备 4.1 基本配置 4.1.1 关闭防火墙[root@oracle ~]# service iptables stopiptables: Setting chains to policy ACCEPT: filter [ OK ]iptables: Flushing firewall rules: [ OK ]iptables: U

ye1992的专栏 5363

postman中 form-data、x-www-form-urlencoded、raw、binary的区别

1、form-data:                    就是http请求中的multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件。当上传的字段是文件时,会有Content-Type来表名文件类型;content-disposition,用来说明字段的一些信息;由于有boundary隔离,所以mu

ye1992的专栏 13万+

ki4so-发起一个史上最开源的sso项目

最近一直在研究单点登录,研究了比较流行的开源单点登录系统——CAS,对其做了比较深入的研究,深入学习了其原理和源代码。对其有一个比较深入的认识,我们公司也是一直在用它实现单点登录,在用的过程中觉得CAS存在以下方面不太适合我们的地方。为什么要开发自己的SSO?1.重量级。CAS作为一个开源的通用的SSO系统,要考虑的东西太多,要遵循的协议也太多,因此在CAS里面有很多其实你根本用不

ye1992的专栏 4914

springMVC–参数绑定常用的注解

springMVC–参数绑定常用的注解简介:handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)A、处理requet uri 部分(这里指uri template中variable,不含queryString部分)的注解:   @PathVariable;B、处理request heade

ye1992的专栏 1万+

linux scp远程拷贝文件及文件夹

1、拷贝本机/home/administrator/test整个目录至远程主机192.168.1.100的/root目录下 复制代码代码如下:scp -r /home/administrator/test/ root@192.168.1.100:/root/2、拷贝单个文件至远程主机 复制代码代码如下:scp /h

ye1992的专栏 1万+

weblogic部署项目:Cannot set web app root system property when WAR file is not expanded

昨天项目 以2种方式进行跑,一种是 war包,一种是 文件夹的形式!tomcat 下面2种方式都没问题。weblogic下面 war包的形式进行部署的话 报如下错误:[java] view plaincopyCaused By: java.lang.IllegalStateException: Cannot set web a

ye1992的专栏 1万+

Java使用Fork/Join框架来并行执行任务

现代的计算机已经向多CPU方向发展,即使是普通的PC,甚至现在的智能手机、多核处理器已被广泛应用。在未来,处理器的核心数将会发展的越来越多。虽然硬件上的多核CPU已经十分成熟,但是很多应用程序并未这种多核CPU做好准备,因此并不能很好地利用多核CPU的性能优势。为了充分利用多CPU、多核CPU的性能优势,级软基软件系统应该可以充分“挖掘”每个CPU的计算能力,决不能让某个CPU处于

ye1992的专栏 1万+

CORS(跨域资源共享) 的配置

各种新版本的ie10,firefox,opera,safari,chrome以及移动版safari和 android浏览器 ie9及一下版本请使用flash方式来兼容通过OPTIONS请求握手一次的方式实现跨根域发送请求,需要服务端配置nginx增加类似如下配置:server {       location / {           if ($ request_me

ye1992的专栏 7296

JavaWeb防止表单重复提交

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。一、表单重复提交的常见应用场景有如下的form.jsp页面 1 @ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

ye1992的专栏 7164

C3P0,Proxool,BoneCP,Druid等连接池的断开自动重联功能

数据库连接池的断开自动重联、失败恢复功能显得很重要,不知道目前主流的数据库连接池:C3P0,Proxool,BoneCP,Druid等支持如何?我知道的:Proxool:?12345678910propertyname="houseKeepingTestSql">value>select 1

ye1992的专栏 1万+

web.xml中webAppRootKey

web.xml中webAppRootKey ------------------------------------------------------------------------------------------------1、 web.xml配置 webAppRootKeywebapp.root"webapp.root"这个字符串可以随便写任何

ye1992的专栏 4327

SecureCRT中文显示乱码

环境:SecureCRT登陆REDHAT5.3 LINUX系统问题:vi编辑器编辑文件时文件中的内容中文显示乱码,但是直接使用linux系统terminal打开此文件时中文显示正常,确诊问题出现在客户端即SecureCRT的显示问题解决方法:1、修改远程linux机器的配置 [root@rhel ~]#vi /etc/sysconfig/i18n  把LANG改成支持UTF-8

ye1992的专栏 918

字符实体:在 HTML 中显示小于号 (<)

字符实体:在 HTML 中显示小于号 ((2011-02-17 16:30:25)转载▼标签:实体小于号字符浏览器大于号分类: php一些字符在 HTML 中拥有特殊的含义,比如小于号 (字符实体有三部分:一个和号 (&),一个实体名称,或者 # 和一个实体编号,以及一个分号 (;)。要在

ye1992的专栏 1万+

WebApp之Meta标签

"添加到主屏幕“后,全屏显示这meta的作用就是删除默认的苹果工具栏和菜单栏。content有两个值”yes”和”no”,当我们需要显示工具栏和菜单栏时,这个行meta就不用加了,默认就是显示。默认值为default(白色),可以定为black(黑色)和black-translucent(灰色半透明)。注意: 若值为“black-translucent”将会占据

ye1992的专栏 734
上一篇: 将免安装绿色版tomcat添加到开机启动
下一篇: poi jxl 生成EXCEL 报表
叶威1
叶威1 企业官方账号 企业官方账号
博客等级 码龄15年 261粉丝 109原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值