论坛首页 Web前端技术论坛

Hibernate——大量save()效率低下的解决方法

浏览 7280 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-02-21  
在用Hibarnate进行大量数据save时,速度会变得很慢,先举个例子如下:

主表-订单:order.hbm.xml
   
	<set name="grnEntries" inverse="false" lazy="false" order-by="ID asc" cascade="all">
			<key>
				<column name="GO_ENTRY_ID" />
			</key>
			<one-to-many class="com.lx100ERP.model.GrnEntries" />
		</set>


子表-订单分录:entry.hbm.xml
 
<many-to-one name="godownEntry" class="com.lx100ERP.model.GodownEntry"
			cascade="all" outer-join="false" update="false" insert="false" fetch="select"
			column="GO_ENTRY_ID" not-null="false">
		</many-to-one>	


通过查看Hibernate在执行save操作的sql,发现执行步骤如下:
1、 先把数据插入主表:


insert into order values(...);

2、 再把数据插入子表
insert into entry values(...);
  insert into entry values(...);
……

3、 最后再把主表的ID插入到子表里:
update entry set order_id = order.id where ...;
  update entry set order_id = order.id where ...;
……

这样做在entry表数据很多的情况下,非常耗时,效率低。

找到了原因,就来看看怎么解决,我们进行手动配置主外键关系维护就行了,就在hibernate配置文件里把inverse改为"true"就行了。

步骤:
1、 修改order.hbm.xml配置信息
		<set name="grnEntries" inverse="true" lazy="false" order-by="ID asc" cascade="all">
			<key>
				<column name="GO_ENTRY_ID" />
			</key>
			<one-to-many class="com.lx100ERP.model.GrnEntries" />
		</set>


2、 修改entry.hbm.xml配置信息
<many-to-one name="godownEntry" class="com.lx100ERP.model.GodownEntry"
			cascade="all" outer-join="false" update="false" insert="true" fetch="select"
			column="GO_ENTRY_ID" not-null="false">
		</many-to-one>
		


3、 代码实现时
IemiTemp iemiTemp = new IemiTemp();
			Set<IemiTempEntry> set = new HashSet<IemiTempEntry>();
			for (String s : str) {
				String[] arr = s.trim().split(",");
				for (String temp : arr) {
					IemiTempEntry entry = new IemiTempEntry();
					temp = temp.trim();
					if (temp == null || "".equals(temp)) {
						continue;
					}
					entry.setIemi(temp);
					//inverse="true" 手动配置主外键关系维护
					entry.setIemiTemp(iemiTemp);
					iemiTemp.getIemiTempEntrys().add(entry);
					set.add(entry);
				}
			}


4、设置后,直接保存order即可
iemiTempService.save(iemiTemp);

   发表时间:2013-02-25  
一般一般 天下第三
0 请登录后投票
   发表时间:2013-03-11  
请讲一下为什么   "在hibernate配置文件里把inverse改为"true"就行了" ?
0 请登录后投票
   发表时间:2013-03-12  
inverse属性告诉hibernate是否由一方维护外键关系。
如果inverse=false表示一方维护外键关联,会产生update语句,而且是根据1方的set来维护,效率比较慢。
建议吧inverse设置成true由多方来维护外键关系,这样就不会产生update语句。
原理和学生知道自己的校长是谁比较容易,而校长都知道自己的学生都有谁就比较麻烦。
0 请登录后投票
   发表时间:2013-03-12  
inverse属性告诉hibernate是否由一方维护外键关系。
如果inverse=false表示一方维护外键关联,会产生update语句,而且是根据1方的set来维护,效率比较慢。
建议吧inverse设置成true由多方来维护外键关系,这样就不会产生update语句。
原理和学生知道自己的校长是谁比较容易,而校长都知道自己的学生都有谁就比较麻烦。
0 请登录后投票
   发表时间:2013-03-12  
inverse属性告诉hibernate是否由一方维护外键关系。
如果inverse=false表示一方维护外键关联,会产生update语句,而且是根据1方的set来维护,效率比较慢。
建议吧inverse设置成true由多方来维护外键关系,这样就不会产生update语句。
原理和学生知道自己的校长是谁比较容易,而校长都知道自己的学生都有谁就比较麻烦。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics