2013-04-03 41 views
3

我在Hibernate中使用以下事務性代碼單元在我的DAO類中插入多行。在Hibernate中插入多行 - 批量插入

@Override 
@SuppressWarnings("unchecked") 
@Transactional(readOnly = false, propagation=Propagation.REQUIRES_NEW, rollbackFor={Throwable.class}) 
public String insertZoneCharge(Long zoneId, List<Object[]> items) 
{ 
    Session session=sessionFactory.openSession(); 
    session.beginTransaction(); 

    //Configuration configuration=new Configuration(); 
    //configuration.setProperty("hibernate.jdbc.batch_size", "50"); 
    int i=1; 

    for(Object[] o:items) 
    { 
     if(o[2]!=null&&StringUtils.isNotBlank(o[2].toString())) 
     { 
      ZoneChargePK zoneChargeId=new ZoneChargePK(); 
      zoneChargeId.setWeightId(Long.parseLong(o[0].toString())); 
      zoneChargeId.setZoneId(zoneId); 

      model.ZoneCharge zoneCharge=new model.ZoneCharge(); 
      zoneCharge.setZoneChargePK(zoneChargeId); 
      zoneCharge.setCharge(new BigDecimal(o[2].toString()).setScale(2, RoundingMode.HALF_UP)); 
      session.save(zoneCharge); 

      if(++i%50==0) 
      { 
       session.flush(); 
       session.clear(); 
      } 
     } 
    } 

    session.getTransaction().commit(); 
    session.close(); 
    return "Data saved successfully."; 
} 

此方法的參數通過JSON請求提供。我沒有深入瞭解Oracle表格細節,因爲它沒有關係。

當我提供讓我們說3個值,這個循環被迭代三次,三行創建到相應的數據庫表。當事務成功完成時,我可以在控制檯上看到的以下本機Oracle INSERT語句看起來會執行三次。

insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?) 

調試和跟蹤信息如下。

DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?) 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 1.00 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 164 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22 

DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?) 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 2.00 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 221 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22 

DEBUG [http-apr-8080-exec-84] (SqlStatementLogger.java:104) - insert into WAGAFASHIONDB.ZONE_CHARGE (CHARGE, WEIGHT_ID, ZONE_ID) values (?, ?, ?) 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [1] as [NUMERIC] - 3.00 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [2] as [BIGINT] - 163 
TRACE [http-apr-8080-exec-84] (BasicBinder.java:83) - binding parameter [3] as [BIGINT] - 22 

所以,看來三個獨立的INSERT報表已執行和三個獨立前往數據庫已經作出。

我希望它在單次旅行中只執行一個多行INSERT聲明。 Hibernate是否真的在這種情況下執行三個單獨的語句?如果是,那麼在特定批次中執行語句的方式是什麼?我的代碼有什麼問題嗎?


我的休眠配置application-context.xml如下。

<property name="hibernateProperties"> 
    <value> 
     hibernate.dialect=org.hibernate.dialect.Oracle10gDialect 
     hibernate.jdbc.batch_size=50 
     hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider    
     hibernate.format_sql=false 
     hibernate.show_sql=true 
     hibernate.order_updates=true 
     hibernate.connection.autocommit=false 
     hibernate.order_inserts=true 
     hibernate.order_updates=true 
     hibernate.cache.use_query_cache=false 
     hibernate.cache.use_second_level_cache=false 
     javax.persistence.validation.mode=callback    
    </value>   
    </property>   
+0

'Configuration configuration = new Configuration(); configuration.setProperty(「hibernate.jdbc.batch_size」,「50」);'是沒有意義的。你必須這樣做,一旦你創建SessionFactory –

+0

@orid - 註釋掉那些語句。 [這個答案](http://stackoverflow.com/a/8310442/1391249)說:「*它只是沒有作出**明確持續**直到事務提交*」。那麼,僅僅在一次數據庫訪問中就不可能做到這一點? – Tiny

回答