关于Hibernate批量处理!

J2EE 码拜 6年前 (2015-05-10) 336次浏览 0个评论
 

需要用hibernate批量进行保存操作,代码如下,其中list里可能会有30W条数据左右,目前已经跑12个小时(weblogic 920),大家讨论下看有没有更好的方法,或者代码方面,配置方面需要更改的!
另外,暂时不考虑通过jdbc,或者存储过程来实现!

  public List<FeePayStream> newSaveFeePayStream(List<FeePayStream> list) throws FeePayManageDaoException {
        Session session = this.getSession();
        int i=0;
        try {
            for (FeePayStream feePayStream : list) {
                session.save(feePayStream);
                i++;
                if(i%50==0)
                {
                    session.flush();
                    session.clear();
                }
            }
        }
        catch (Exception e) {
            throw new FeePayManageDaoException(e.getMessage());
        }
        finally {
            session.flush();
            session.clear();
        }
        return list;
    }
我先顶起,欢迎大家提出自己的建议!
继续在线等大家的发言和建议!
用循环地方法只是定时清空缓存,
如果用jdbc的话,都需要用batch,所以可以设置hibernate的batch size来提高速度
比如hibernate.jdbc.batch_size=50,把log4j设置成error
楼上说的早就用过了!
跟数据库有关吧,有的数据库插入时是锁表的,ORACLE好像不是,用subList配合多线程应该可以提高一些
建议采用BatchPreparedStatementSetter。
getJdbcTemplate().batchUpdate(String sql, BatchPreparedStatementSetter setter)。
可以批量处理。
String sql = “insert into table_name (db field list) values (?, ?, …)”;
BatchPreparedStatementSetter setter = BatchPreparedStatementSetter()
{
    public int getBatchSize()
    {
        return size;
    }

    public void setValues(PreparedStatement ps, int index) throws SQLException
    {
       //从list中根据index取出对象
       //ps.setXXX(int index, Object value);
    }
};
getJdbcTemplate().batchUpdate(sql, setter);

赞同,接分 
说了:另外,暂时不考虑通过jdbc,或者存储过程来实现!
那用getHibernate().saveOrUpdateAll(Collection collection)实现吧。
可以根据你数据条目数的大小设置Collection的大小。
引用 11 楼 M_song 的回复:

说了:另外,暂时不考虑通过jdbc,或者存储过程来实现!

hibernate这种or工具,处理大数据量本身就不是强项,还可以用StatelessSession配合batch来实现大数据量操作,代码如下:

		StatelessSession session = getSessionFactory().openStatelessSession();
		Transaction tx = session.beginTransaction();
		for (int i=0;i<10000;i++) {
			session.insert(...);
        }
		tx.commit();
		session.close();

StatelessSession不参与hibernate的各种缓存,默认的隔离级别对他也不起作用,直接生成sql直接执行,类似jdbc。但是他需要自己去写事务提交,spring好像也拦截不到它
如果batch设置成100的话,那么会每一百次执行一次同步一次数据库

有一个注意的地方:如果表中的主键是identity的话,那么batch就会失效,直接用jdbc也是一样失效

30W条数据左右,目前已经跑12个小时
这个应该是有问题的

可以考虑一下分成不同的批次,进行多线程处理。

学习。
你可以把数据分开,同时跑线程,进行存数据.
目前的结果:
跑30w条数据,用时大约130.045S!
上面代码几乎没变,环境方面重新设置了下,另外把hibernate的二级缓存关掉了,又给weblogic增加了点内存,另外又多开了几个线程!
如果启用了二级缓存,从机制上讲Hibernate为了维护二级缓存,我们在做插入、更新、删除操作时,Hibernate都会往二级缓存充入相应的数据,性能上就会有很大损失!
优化起来貌似 有点困难。 内存中咋能出现 30w数据呢。可以从数据获取端去优化。
30W,如果数据量不是很大,应该1-2分钟就结束了。

你启动事务吧。我只看到了session,可是没看到事务。

关于Hibernate批量处理!

用的啥数据库啊?直接采用数据库里面存,也需要花大量的时间,何况,程序呢?电脑配置快,数据库快,就行了
学习中
事务是统一配置的!
mark
不是我说啊,太注重性能,就别用Hibernate,哈
学习了
跟楼上的,不要用session,用statelesssession。
大批量的数据还是用sql比较好吧,这本来就是Hibernate的弱点。
大批量的数据还是用sql比较好吧,这本来就是Hibernate的弱点。
好贴   学习了
用jdbc是最快的,但是不考虑用,看看用多线程,或者分成多次来处理,处理1次,让线程sleep 一下
up
这种情况只能用存储过程搞,无论用hibernate还是jdbc 都是错误的。
200分
用jdbc是最快的,但是不考虑用,最好用多线程
明显刷分嫌疑

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于Hibernate批量处理!
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!