- 浏览: 886170 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
部分内容转自 :http://gaolixu.iteye.com/blog/519086
部分内容转自 :http://superjavason.iteye.com/blog/255423
--------------------------------------------------------------------------------------------
hibernate.jdbc.fetch_size 50
hibernate.jdbc.batch_size 25
这面这两项属性很重要
配置方法如下:
<session-factory>
...
<property name="hibernate.jdbc.batch_size">50</property>
...
</session.factory>
--------------------------------------------------
Fetch Size (抓取大小):
是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。
一般我们查询时会返回一个ResultSet对象,他其实是一个数据库的游标,要时刻保持与数据库的连接,不可断开。
例如一次查询结果是1万条记录,对于Oracle的JDBC驱动来说,是不会1次性把1万条结果全返出来的,而只会返出Fetch Size数量的记录,当不够用时,再去数据库取Fetch Size条数据,当然这一过程你是完全感觉不出来的。
Fetch Size设的越大,读数据库的次数越少,速度越快,越耗内存;
Fetch Size设的越小,读数据库的次数越多,速度越慢,前期会省内存(后期1万条都读出来了还是要用内存的)。
Oracle数据库的JDBC驱动默认的Fetch Size=10,是一个非常保守的设定,根据我的测试,当Fetch Size=50的时候,性能会提升1倍之多,当Fetch Size=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。
因此我建议使用Oracle的一定要将Fetch Size设到50。
不过并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持。
MySQL就像我上面说的那种最坏的情况,他总是一下就把1万条记录完全取出来,内存消耗会非常非常惊人!这个情况就没有什么好办法了 :(
---------------------------------------------------------------------------
Batch Size是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。
Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。我做的一个测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!!!
这有点像平时我们写程序写硬盘文件一样,设立一个Buffer,每次写入Buffer,等Buffer满了以后,一次写入硬盘,道理相同。
-----------------------------------------------------------------------------
hibernate.max_fetch_depth 设置外连接抓取树的最大深度取值. 建议设置为0到3之间
就是每次你在查询时,会级联查询的深度,譬如你对关联vo设置了eager的话,如果fetch_depth值太小的话,会发多很多条sql
-----------------------------------------------------------------------------
1 伪批量删除
- public void delete(final List<Integer> ids)
- {
- final Session session = hibernateUtil.getCS();
- final Query q = session.createQuery("delete from Img where userId=:userId and id in(:ids)");
- final User user = (User) ActionContext.getContext().getSession().get("s");
- q.setInteger("userId", user.getId());
- q.setParameterList("ids", ids);
- q.executeUpdate();
- }
public void delete(final List<Integer> ids) { final Session session = hibernateUtil.getCS(); final Query q = session.createQuery("delete from Img where userId=:userId and id in(:ids)"); final User user = (User) ActionContext.getContext().getSession().get("s"); q.setInteger("userId", user.getId()); q.setParameterList("ids", ids); q.executeUpdate(); }
2 批量插入
大家说下面的代码,50次flush一下, 如果同时也设置了<property name="hibernate.jdbc.batch_size">40(或其它值)</property>会怎么样呢?
- Session session = sessionFactory.openSession();
- Transaction tx = session.beginTransaction();
- for ( int i=0; i<100000; i++ ) {
- Customer customer = new Customer(.....);
- //如果你的 hibernate.cache.use_second_level_cache 是 true, 请在会话级别上关闭他
- //向(任何一级)缓存中加载大量数据通常也意味着它们很快会被清除出去,这会增加GC开销。
- session.setCacheMode(CacheMode.IGNORE);
- session.save(customer);
- if ( i % 50 == 0 ) {
- //将本批插入的对象立即写入数据库并释放内存
- session.flush();
- session.clear();
- }
- }
- tx.commit();
- session.close();
Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i<100000; i++ ) { Customer customer = new Customer(.....); //如果你的 hibernate.cache.use_second_level_cache 是 true, 请在会话级别上关闭他 //向(任何一级)缓存中加载大量数据通常也意味着它们很快会被清除出去,这会增加GC开销。 session.setCacheMode(CacheMode.IGNORE); session.save(customer); if ( i % 50 == 0 ) { //将本批插入的对象立即写入数据库并释放内存 session.flush(); session.clear(); } } tx.commit(); session.close();
--------------------------------------------------------------------------------------------------------------
JDBC批量操作
Statement加批量的方法
- conn.setAutoCommit(false);
- Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
- for(int x = 0; x < size; x++){
- stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')");
- }
- stmt.executeBatch();
- conn.commit();
conn.setAutoCommit(false); Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); for(int x = 0; x < size; x++){ stmt.addBatch("INSERT INTO adlogs(ip,website,yyyymmdd,hour,object_id) VALUES('192.168.1.3', 'localhost','20081009',8,'23123')"); } stmt.executeBatch(); conn.commit();
使用PreparedStatement加批量的方法
- try {
- Class.forName("com.mysql.jdbc.Driver");
- conn = DriverManager.getConnection(o_url, userName, password);
- conn.setAutoCommit(false);
- String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)";
- PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
- for(int x = 0; x < size; x++){
- prest.setString(1, "192.168.1.1");
- prest.setString(2, "localhost");
- prest.setString(3, "20081009");
- prest.setInt(4, 8);
- prest.setString(5, "11111111");
- prest.addBatch();
- }
- prest.executeBatch();
- conn.commit();
- conn.close();
- } catch (SQLException ex) {
- Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);
- } catch (ClassNotFoundException ex) {
- Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex);
- }
try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(o_url, userName, password); conn.setAutoCommit(false); String sql = "INSERT adlogs(ip,website,yyyymmdd,hour,object_id) VALUES(?,?,?,?,?)"; PreparedStatement prest = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); for(int x = 0; x < size; x++){ prest.setString(1, "192.168.1.1"); prest.setString(2, "localhost"); prest.setString(3, "20081009"); prest.setInt(4, 8); prest.setString(5, "11111111"); prest.addBatch(); } prest.executeBatch(); conn.commit(); conn.close(); } catch (SQLException ex) { Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { Logger.getLogger(MyLogger.class.getName()).log(Level.SEVERE, null, ex); }
注意上面JDBC驱动使用的是mysql的, 好像不支持批量更新,所以大家一定要使用oracle的JDBC驱动试验啊。
发表评论
-
Criteria查询,DetachedCriteria离线查询 --做综合查询
2011-09-06 00:25 1591通过Session得到Criteria类的对象 Ja ... -
Hibernate懒加载深入分析
2011-09-06 00:19 1321懒加载可以提高性能吗? 不可以简单的说"能" ... -
getSesson currentSession
2011-09-06 00:15 9981 getCurrentSession创建的session会和 ... -
Hibernate 操作Blob Clob
2011-09-05 23:46 1065Photo.java Java代码 i ... -
Hibernate建表错误,Could not determine type for: java.util.List
2011-04-04 22:19 1638今天遇到 Could not determine type f ... -
Hibernate的fetch="join"和fetch="select"
2011-03-24 14:16 966fetch参数指定了关联对 ... -
Hibernate的Criteria用法总结
2011-03-23 10:53 774最近在项目中使用 Struts 和 Hibernate 进行开 ... -
第29讲--为Spring集成的Hibernate配置二级缓存
2011-03-10 23:16 1098合理的使用缓存策略,往往在web开发中提高性能起到关键作用。 ... -
hibernate抓取策略
2011-02-12 13:23 816Hibernate最让人头大的就是对集合的加载形式。书看了N次 ... -
Hibernate笔记:HQL查询总结(一)——简单属性查询和实体对象查询
2011-02-01 23:38 3488本文一部分转自kuangbaoxu的博文hibernate-- ... -
Hibernate笔记:HQL查询总结(二)——条件查询
2011-02-01 23:35 1505条件查询 1.拼字符串 where条件后面,可以用字 ... -
Hibernate属性延迟加载
2011-02-01 21:28 1009Hibernate3开始增加了通过property节点的la ... -
Hibernate中的cascade和inverse
2011-01-31 00:31 992这两个属性都用于一多对或者多对多的关系中。而inverse特别 ... -
batch_size 和 fetch_size作用
2010-12-01 21:37 1277hibernate抓取策略,,batch-szie在< ... -
hibernate中SQLQuery的addEntity();方法
2010-10-20 10:48 2768如果使用原生sql语句进行query查询时,hibernate ... -
Hibernate的evict方法错误总结
2010-10-14 10:08 1207摘自百度知道:http://zhi ... -
hibernate中get方法和load方法的区别
2010-10-14 09:57 798键字: hibernate get load 区 ... -
Hibernate: 设A引用了B,则删A后可能要evict(A.getB())
2010-10-14 09:56 999Hibernate: 设A引用了B,如果要先取A删A再取B删B ... -
Hibernate的flush()和evict()总结
2010-10-14 09:53 1321关键字: hibernate flush() evict() ... -
flush,commit,evict
2010-10-14 09:52 919Flush()后只是将Hibernate缓存中的数据提交到数据 ...
相关推荐
Hibernate作为一款流行的Java持久层框架,支持通过其自身的API或直接使用JDBC来执行这些批量操作。 #### 批量删除概述 Hibernate本身提供了一种批量删除的方式,但由于它是逐条执行删除操作的,因此当数据量较大时...
需要注意的是,如果启用二级缓存,批量操作可能导致额外的内存问题,因为Hibernate需要在事务结束时同步二级缓存。在这种情况下,可能需要临时禁用二级缓存以避免不必要的内存消耗。 总的来说,虽然ORM框架在处理...
此外,数据库引擎可以更有效地处理批量操作,因为它不必为每个单独的插入记录事务日志。 为了测试`hibernate.jdbc.batch_size`的效果,你需要创建一个包含大量数据的场景。在`hibernate-batch-size-test-master`这...
### Hibernate批量处理详解 #### 一、批量处理概述 Hibernate作为一种强大的对象关系映射(ORM)框架,提供了多种批量处理的方式以提高数据处理效率。批量处理对于需要在短时间内处理大量数据的应用尤其重要,如...
概述:本文主要介绍了Hibernate+JDBC实现批量插入、更新及删除的方法,通过实例形式详细分析了Hibernate与JDBC针对数据库的批量操作相关实现技巧。 知识点一:Hibernate一级缓存 * Hibernate一级缓存对其容量没有...
在 Hibernate 配置文件中,可以设置 `hibernate.jdbc.batch_size` 参数来指定批量抓取的大小。 如何实现批量更新 在 Controller 层,需要将大量数据插入到数据库时,可以使用以下方法: ```java for (int i = 0; ...
通过合理利用Hibernate的会话缓存机制、手动提交与清理策略、直接使用JDBC API或通过存储过程调用数据库原生批量操作,可以有效提升批量操作的性能和效率。开发者应当根据具体的应用场景和数据库特性,选择合适的...
2. **使用原生SQL或存储过程**:直接使用JDBC API执行原生SQL或调用存储过程,绕过Hibernate的ORM层,可以实现更高性能的批量操作。例如,可以创建一个存储过程用于批量更新操作: ```sql CREATE OR REPLACE ...
- **批量操作**:对于批量创建或更新操作,Hibernate的性能也往往优于JDBC。这是因为Hibernate可以通过缓存机制减少与数据库之间的交互次数,提高效率。 - **内存管理**:Hibernate通过其内部的缓存机制可以有效地...
本文件主要探讨了如何使用Hibernate进行批量更新和批量删除处理,这些操作在处理大量数据时尤其重要,因为它们可以显著提高应用的性能。下面我们将深入解析这两个主题。 批量更新在Hibernate中通常涉及在一个事务中...
以下是针对Hibernate批量处理海量数据的一些关键知识点和优化策略: 1. **理解Hibernate的工作原理**:Hibernate通过查询数据库获取数据,并将其转化为Java对象存储在内存中,这种做法在处理小量数据时非常便捷,但...
在Java的持久化框架Hibernate中,管理Session和执行批量操作是优化数据库交互的关键技术。本文主要探讨了如何高效地管理Hibernate的Session以及如何实施批量处理数据,这些技巧对于提升应用程序性能至关重要。 首先...
Hibernate.jdbc.batch_size 属性用于控制 Hibernate 的批量更新。如果设置为非零值,Hibernate 将使用 JDBC2 的批量更新。 hibernate.jdbc.batch_versioned_data Hibernate.jdbc.batch_versioned_data 属性用于...
- 使用批处理:批量处理多个保存、更新或删除操作,以减少数据库交互次数。 - 适当使用懒加载和立即加载:避免加载不必要的关联对象,减小内存开销。 - 优化HQL和SQL:避免全表扫描,利用索引,减少子查询。 ...
2. **批量操作**:`saveAll()`, `updateAll()`, `deleteAll()`等,用于处理大量数据。 3. **查询接口**:提供基于HQL(Hibernate Query Language)或SQL的查询方法,如`findByExample()`, `findByName()`, `findAll...
虽然JDBC提供了直接操作数据库的能力,但在实际开发中,为了提高开发效率和代码可维护性,常使用Hibernate、MyBatis等ORM(Object-Relational Mapping)框架,它们在JDBC基础上封装了一层,提供了更高级别的抽象。...
然而,对于大数据量的批量处理,Hibernate的性能可能不如直接使用JDBC或其他低级数据库操作高效。这是因为Hibernate在默认情况下会缓存对象,以便在事务提交时进行一次性持久化,这可能导致内存消耗过大,尤其是在...
在Java的软件开发中,Hibernate是一个...总结起来,Hibernate虽然提供了面向对象的便捷操作,但在处理批量更新和删除时,可能需要结合JDBC API来优化性能。理解和掌握这些技巧对于开发高效、大规模的Java应用至关重要。
9. **批量操作** Hibernate支持批处理,比如批处理更新和插入,可以显著提高数据库操作的性能。通过设置`hibernate.jdbc.batch_size`配置,可以指定一次提交的SQL语句数量。 10. **事件监听器** Hibernate提供了...
我们可以设置一个合理的 JDBC 批处理大小,例如 hibernate.jdbc.batch_size 20,然后在一定间隔对 Session 进行 flush() 和 clear()。这样可以避免内存溢出错误,并提高性能。 在批量插入数据时,我们可以使用以下...