??xml version="1.0" encoding="utf-8" standalone="yes"?>日本一区二区三区视频视频 ,国产精品亚洲产品,国产一区二区三区日韩精品http://www.aygfsteel.com/kevinzheng/zh-cnThu, 19 Jun 2025 11:37:57 GMTThu, 19 Jun 2025 11:37:57 GMT60Hibernate中如何高效处理v量数?/title><link>http://www.aygfsteel.com/kevinzheng/archive/2008/12/19/247401.html</link><dc:creator>kevinzheng</dc:creator><author>kevinzheng</author><pubDate>Fri, 19 Dec 2008 14:03:00 GMT</pubDate><guid>http://www.aygfsteel.com/kevinzheng/archive/2008/12/19/247401.html</guid><wfw:comment>http://www.aygfsteel.com/kevinzheng/comments/247401.html</wfw:comment><comments>http://www.aygfsteel.com/kevinzheng/archive/2008/12/19/247401.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/kevinzheng/comments/commentRss/247401.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/kevinzheng/services/trackbacks/247401.html</trackback:ping><description><![CDATA[<p>最q一直常常看到别人javaeye|站上看到别人在问在hibernate怎么样处理v量数据,怎么h高性能Q本人在CSDN博客上看到这好的文章,q结合本Z一验证 实如作者所?故拿出来和大家分享。希望对初学HIBERNATE框架的朋友有所帮助?<br /> Hibernate扚w处理量其实从性能上考虑Q它是很不可取的Q浪费了很大的内存。从它的机制上讲QHibernate它是先把W合条g的数据查出来Q放到内存当中,然后再进行操作。实际用下来性能非常不理惻I在笔者的实际使用中采用下面的W三U优化方案的数据是:100000条数据插入数据库Q?nbsp;需要约30分钟Q呵呵,晕倒。(本h10分钟插入1000000条数据(字段比较?yu))我的爱机是宏基Aspire 4920Q?<br />     ȝ下来有三U来处理以解x能问题Q?</p> <p>    1Q绕qHibernate API Q直接通过 JDBC API 来做Q这个方法性能上是比较好的。也是最快的?</p> <p>    2Q运用存储过E?</p> <p><br />     3Q还是用Hibernate API 来进行常规的扚w处理Q可以也有变Q变变在,我们可以在查扑և一定的量的时候,及时的将q些数据做完操作?</p> <p><br />     删掉Qsession.flushQ)Qsession.evictQXX对象集)Q?q样也可以挽救一Ҏ(gu)能损失。这?#8220;一定的?#8221;要就要根据实际情况做定量参考了。一般ؓ30-60左右Q但效果仍然不理惟?</p> <p>    1Q绕qHibernate API Q直接通过 JDBC API 来做Q这个方法性能上是比较好的Q也是最快的。(实例?更新操作Q?</p> <p> </p> <p>    Transaction tx=session.beginTransactionQ)Q?//注意用的是hibernate事务处理边界 </p> <p><br />     Connection conn=session.connectionQ)Q?</p> <p><br />     PreparedStatement stmt=conn.preparedStatementQ?update CUSTOMER as C set C.sarlary=c.sarlary+1 where c.sarlary>1000"Q; </p> <p> </p> <p>    stmt.excuteUpdateQ)Q?</p> <p>    tx.commitQ)Q?//注意用的是hibernate事务处理边界 </p> <p><br />     q小E序中,采用的是直接调用JDBC 的API 来访问数据库Q效率很高。避免了Hibernate 先查询出来加载到内存Q再q行操作引发的性能问题 </p> <p> </p> <p>    ?</p> <p>    2Q运用存储过E。但q种方式考虑到易植和E序部v的方便性,不徏议用。(实例?更新操作Q?</p> <p> </p> <p>    如果底层数据库(如OracleQ支持存储过E,也可以通过存储q程来执行批量更新。存储过E直接在数据库中q行Q速度更加快。在Oracle?</p> <p>    据库中可以定义一个名为batchUpdateCustomerQ)的存储过E,代码如下Q?</p> <p> </p> <p>    代码内容create or replace procedure batchUpdateCustomerQp_age in numberQ?as begin update CUSTOMERS set AGE=AGE+1 where AGE>p_ageQendQ?</p> <p>    以上存储q程有一个参数p_ageQ代表客Lq龄Q应用程序可按照以下方式调用存储q程Q?</p> <p>    代码内容 </p> <p><br />     tx = session.beginTransactionQ)Q?</p> <p><br />     Connection con=session.connectionQ)Q?</p> <p><br />     String procedure = "{call batchUpdateCustomerQ?Q?}"Q?</p> <p><br />     CallableStatement cstmt = con.prepareCallQprocedureQ; </p> <p>    cstmt.setIntQ?Q?Q; //把年龄参数设? </p> <p>    cstmt.executeUpdateQ)Q?</p> <p>    tx.commitQ)Q?</p> <p><br />     从上面程序看出,应用E序也必ȝqHibernate APIQ直接通过JDBC API来调用存储过E?</p> <p> </p> <p><br /> 3Q还是用Hibernate API 来进行常规的扚w处理Q可以也有变Q变变在,我们可以在查扑և一定的量的时候,及时的将q些数据做完操作?</p> <p>    删掉Qsession.flushQ)Qsession.evictQXX对象集)Q?q样也可以挽救一Ҏ(gu)能损失。这?#8220;一定的?#8221;要就要根据实际情况做定量参考了…… </p> <p> </p> <p>    Q实例ؓ 保存操作Q?</p> <p><br />     业务逻辑为:我们要想数据库插?0 0000 条数?</p> <p> </p> <p>    tx=session.beginTransactionQ)Q?</p> <p>    forQint i=0Qi<100000Qi++Q?</p> <p><br />     { </p> <p>    Customer custom=new CustomerQ)Q?</p> <p> </p> <p>    custom.setNameQ?user"+iQ; </p> <p><br />     session.saveQcustomQ; </p> <p> </p> <p>    ifQi%50==0Q?// 以每50个数据作Z个处理单元,也就是我上面说的“一定的?#8221;Q这个量是要酌情考虑?</p> <p> </p> <p>    { </p> <p>    session.flushQ)Q?</p> <p>    session.clearQ)Q?</p> <p> </p> <p>    } </p> <p>    } </p> <p> </p> <p>    q样可以把系l维持在一个稳定的范围…… </p> <p>    在项目的开发过E之中,׃目需求,我们常常需要把大批量的数据插入到数据库。数量有万U、十万、百万、甚臛_万别的。如此数量别的数据用Hibernate做插入操作,可能会发生异常Q常见的异常是OutOfMemoryErrorQ内存溢出异常)?</p> <p>    首先Q我们简单来回顾一下Hibernate插入操作的机制。Hibernate要对它内部缓存进行维护,当我们执行插入操作时Q就会把要操作的对象全部攑ֈ自n的内部缓存来q行理?</p> <p>    谈到Hibernate的缓存,Hibernate有内部缓存与二~存之说。由于Hibernate对这两种~存有着不同的管理机Ӟ对于二~存Q我们可以对它的大小q行相关配置Q而对于内部缓存,Hibernate采取了“放Q自流”的态度了,对它的容量ƈ没有限制。现在症l找CQ我们做量数据插入的时候,生成q么多的对象׃被纳入内部缓存(内部~存是在内存中做~存的)Q这样你的系l内存就会一点一点的被蚕食,如果最后系l被?#8220;?#8221;了,也就在情理之中了?</p> <p>    我们x如何较好的处理这个问题呢Q有的开发条件又必须使用Hibernate来处理,当然有的目比较灉|Q可以去L其他的方法?</p> <p><br />     W者在q里推荐两种Ҏ(gu)Q(1Q:优化HibernateQ程序上采用分段插入及时清除~存的方法?</p> <p>    Q?Q:l过Hibernate API Q直接通过 JDBC API 来做扚w插入Q这个方法性能上是最 好的Q也是最快的?</p> <p>    对于上述中的Ҏ(gu)1Q其基本是思\为:优化HibernateQ在配置文g中设|hibernate.jdbc.batch_size参数Q来指定每次提交SQL的数量;E序上采用分D|入及时清除缓存的Ҏ(gu)QSession实现了异步write-behindQ它允许Hibernate昑ּ地写操作的批处理Q,也就是每插入一定量的数据后及时的把它们从内部缓存中清除掉,释放占用的内存?</p> <p>    讄hibernate.jdbc.batch_size参数Q可参考如下配|?</p> <p><br />     <hibernate-configuration> <session-factory>…… </p> <p> </p> <p>    <property name=“ hibernate.jdbc.batch_size”>50</property>…… </p> <p><br />     <session-factory> <hibernate-configuration> </p> <p>    配置hibernate.jdbc.batch_size参数的原因就是尽量少L据库Qhibernate.jdbc.batch_size参数D大,L据库的次数越,速度快。从上面的配|可以看出,Hibernate是等到程序积累到?0个SQL之后再批量提交?</p> <p>    W者也在想Qhibernate.jdbc.batch_size参数g可能不是讄得越大越好,从性能角度上讲q有待商榗这要考虑实际情况Q酌情设|,一般情形设|?0?0可以满需求了?</p> <p>    E序实现斚wQ笔者以插入10000条数据ؓ例子Q如 </p> <p> </p> <p>    Session session=HibernateUtil.currentSessionQ)Q?</p> <p>    Transatcion tx=session.beginTransactionQ)Q?</p> <p>    forQint i=0Qi<10000Qi++Q?</p> <p> </p> <p>    { </p> <p>    Student st=new StudentQ)Q?</p> <p> </p> <p>    st.setNameQ?#8220;feifei”Q; </p> <p> </p> <p>    session.saveQstQ; </p> <p>    ifQi%50==0Q?//以每50个数据作Z个处理单?</p> <p>    { </p> <p>    session.flushQ)Q?//保持与数据库数据的同?</p> <p><br />     session.clearQ)Q?//清除内部~存的全部数据,及时释放出占用的内存 </p> <p>    } </p> <p>    } </p> <p> </p> <p>    tx.commitQ)Q?</p> <p>    …… </p> <p> </p> <p><br />     在一定的数据规模下,q种做法可以把系l内存资源维持在一个相对稳定的范围?</p> <p> </p> <p>    注意Q前面提CU缓存,W者在q里有必要再提一下。如果启用了二~存Q从机制上讲HibernateZl护二~存Q我们在做插入、更新、删除操作时QHibernate都会往二~存充入相应的数据。性能上就会有很大损失Q所以笔者徏议在批处理情况下用二~存?</p> <p><br />     对于Ҏ(gu)2Q采用传l的JDBC的批处理Q用JDBC API来处理?</p> <p>    些方法请参照java 批处理自执行SQL </p> <p><br />     看看上面的代码,是不是总觉得有不妥的地方?对,没发CQ这q是JDBC的传l编E,没有一点Hibernate味道?</p> <p> </p> <p>    可以对以上的代码修改成下面这P </p> <p> </p> <p>    Transaction tx=session.beginTransactionQ)Q?//使用Hibernate事务处理 </p> <p>    边界Connection conn=session.connectionQ)Q?</p> <p>    PrepareStatement stmt=conn.prepareStatementQ?#8220;insert into T_STUDENTQnameQ?valuesQ?Q?#8221;Q; </p> <p>    forQint j=0Qj++Qj<200Q{ </p> <p><br />     forQint i=0Qi++Qj<50Q?</p> <p> </p> <p>    { </p> <p>    stmt.setStringQ?Q?#8220;feifei”Q; </p> <p><br />     } </p> <p>    } </p> <p>    stmt.executeUpdateQ)Q?</p> <p> </p> <p>    tx.commitQ)Q?//使用 Hibernate事务处理边界 </p> <p>    …… </p> <p><br />     q样改动很有Hibernate的味道了。笔者经q测试,采用JDBC API来做扚w处理Q性能上比使用Hibernate API要高近10倍,性能上JDBC 占优q是无疑的?</p> <p><br />     扚w更新与删?</p> <p>    Hibernate2中,对于扚w更新操作QHibernate是将W合要求的数据查出来Q然后再做更新操作。批量删除也是这P先把W合条g的数据查出来Q然后再做删除操作?</p> <p>    q样有两个大~点Q(1Q:占用大量的内存?</p> <p>    Q?Q:处理量数据的时候,执行update/delete语句是量了,而且一条update/delete语句只能操作一个对象,q样频繁的操作数据库Q性能低下应该是可惌知的了?</p> <p>    Hibernate3 发布后,Ҏ(gu)量更?删除操作引入了bulk update/deleteQ其原理是通过一条HQL语句完成扚w更新/删除操作Q很cMJDBC的批量更?删除操作。在性能上,比Hibernate2的批量更?删除有很大的提升?</p> <p>    Transaction tx=session.beginSessionQ)Q?</p> <p>    String HQL=“delete STUDENT”Q?</p> <p>    Query query=session.createQueryQHQLQ; </p> <p><br />     int size=query.executeUpdateQ)Q?</p> <p> </p> <p>    tx.commitQ)Q?</p> <p> </p> <p>    …… </p> <p>    控制台输Z也就一条删除语句HibernateQdelete from T_STUDENTQ语句执行少了,性能上也与用JDBC相差无几Q是一个提升性能很好的方法。当然ؓ了有更好的性能Q笔者徏议批量更C删除操作q是使用JDBCQ方法以及基本的知识点与上面的批量插入方?基本相同Q这里就不在冗述?</p> <p>    W者这里再提供一个方法,是从数据库端来考虑提升性能Q在HibernateE序端调用存储过E。存储过E在数据库端q行Q速度更快。以扚w更新ZQ给出参考代码?</p> <p>    首先在数据库端徏立名为batchUpdateStudent存储q程Q?</p> <p>    create or replace produre batchUpdateStudentQa in numberQ?as </p> <p> </p> <p>    begin </p> <p><br />     update STUDENT set AGE=AGE+1 where AGE>aQ?</p> <p><br />     endQ?</p> <p>    调用代码如下Q?</p> <p> </p> <p>    Transaction tx=session.beginSessionQ)Q?</p> <p><br />     Connection conn=session.connectionQ)Q?</p> <p><br />     String pd=“……{call batchUpdateStudentQ?Q}”Q?</p> <p><br />     CallableStatement cstmt=conn.PrepareCallQpdQ; </p> <p>    cstmt.setIntQ?Q?0Q; //把年龄这个参数设?0 </p> <p>    tx.commitQ)Q?</p> <p>    观察上面的代码,也是l过Hibernate APIQ?JDBC API来调用存储过E,使用的还是Hibernate的事务边界。存储过E无疑是提高扚w处理性能的一个好Ҏ(gu)Q直接运行与数据库端Q某U程度上讲把批处理的压力转接l了数据库?</p> <p><br />     三:~后?</p> <p>    本文探讨了Hibernate的批处理操作Q出发点都是在提高性能上考虑了,也只是提供了提升性能的一个小斚w?</p> <p>    不管采取什么样的方法,来提升性能都要Ҏ(gu)实际的情冉|考虑Qؓ用户提供一个满需求的而且高效E_的系l才是重中之中?/p> <p> </p> <img src ="http://www.aygfsteel.com/kevinzheng/aggbug/247401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/kevinzheng/" target="_blank">kevinzheng</a> 2008-12-19 22:03 <a href="http://www.aygfsteel.com/kevinzheng/archive/2008/12/19/247401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">׺</a>| <a href="http://" target="_blank">绯</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ͽ</a>| <a href="http://" target="_blank">ԭ</a>| <a href="http://" target="_blank">㽭ʡ</a>| <a href="http://" target="_blank">˿</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ٹ</a>| <a href="http://" target="_blank">Ϊ</a>| <a href="http://" target="_blank">ؿ˹</a>| <a href="http://" target="_blank">ԭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">Ӻ</a>| <a href="http://" target="_blank">˷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʹ</a>| <a href="http://" target="_blank">Ӣ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӱ</a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͭɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʤ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>