2012-11-24 67 views
0

我節省表項創建模式,只有當他們已經存在:優化得到或休眠

public static Email getOrCreate(Session sess, String address) { 
    if (address==null) return null; 
    List l = sess.createQuery("SELECT email FROM Email email WHERE email.address=:address").setString("address", address).list(); 
    if (l.size() > 0) 
     return (Email) l.get(0); 
    Email email = new Email(address); 
    sess.save(email); 
    return email; 
} 

我不滿意這個過程的速度。我需要約5分鐘才能保存5000條複雜記錄,並且有50%的時間被此功能佔用。我的休眠緩存設置爲: cfg.setProperty(「hibernate.cache.provider_class」,「org.hibernate.cache.EhCacheProvider」);

當然,我可以創建靜態地圖並與數據庫同步,但它看起來有點難看。冬眠可以做這樣的事情嗎?感謝名單。

回答

1

做到在批處理:

Set<String> addresses = ...; 
List<String> existingAddresses = 
    session.createQuery("select email.address from Email email where email.address in :addresses") 
      .setParameterList("addresses", addresses) 
      .list(); 
addresses.removeAll(existingAddresses); 
for (String address : addresses) { 
    session.save(new Email(address)); 
} 

確保,雖然,你的數據庫允許在IN條款5000元。例如,Oracle將它們限制爲1000.但是,您仍然可以只執行5個請求,而不是5000.

也就是說,5分鐘的時間對我來說看起來很像。你有沒有在email.address上定義的數據庫索引?

+0

我的架構不允許我才能完成設置地址... –

+0

如果你能迭代,並調用該方法5000次,那麼你應該能夠重複和收集5000個地址爲一組,不該你呢? –

+0

我正在導入郵件。電子郵件來自不同的應用程序的地方。所以有可能收集所有這些,但這看起來非常難看。也許可以實現這種推遲的方式?即已創建子類電子郵件,其中包含其他一些電子郵件? –