2015-05-20 109 views
1

我有一個外部服務,我從中抓取項目列表,並在這些項目和用戶之間保持本地關係。我爲該外部服務提供一個名稱,並返回具有該名稱的關聯項目。我選擇在本地保留它們,因爲一旦我的應用程序發現了這些外部項目,我想保留自己的屬性。這些項目本身是非常靜態的對象,但它們的總數對於我來說是未知的,並且我唯一知道的是新用戶在外部服務上與他們有關聯。快速檢查數據庫中是否存在一組項目

當我從外部服務獲取它們的列表時,我想先檢查它們是否存在於我的數據庫中,然後使用該對象,但如果它不是,則需要添加它們,以便設置我的擁有自己的屬性,並保持關聯到我的用戶。

現在我有以下的(僞代碼,因爲它分解爲服務層等):

Set<ExternalItem> items = externalService.getItemsForUser(user.name); 
for (ExternalItem externalItem : items){ 
    Item dbItem = sessionFactory.getCurrentSession().get(Item.class,item.id); 
    if (dbitem == null){ 
     //Not in database, create it. 
     dbItem = mapToItem(externalItem); 
    } 
    user.addItem(dbItem); 

} 
sessionFactory.getCurrentSession().save(user);//Saves the associated Items also. 

此操作正在進行的時間是大約16秒,約500外部項目。遠程操作大約1秒鐘,保存也可以忽略不計。我注意到的漏洞來自我正在做的衆多session.get(Item.class,item.id)調用。

有沒有更好的方法來檢查我的數據庫中的現有項目比這個,因爲我從我的外部服務得到一個回退?

注:外部項目的id是可靠的是和我一樣,和一個ID將始終代表相同的外部項

+0

如果你不想添加另一個數據結構(過濾器),我可以想象的唯一幫助就是減少往返數據庫的次數(並確保itemID上有一個索引)。通過使用帶有IN(id1,id2,id3)結構的本地SQL查詢可以減少往返次數。不幸的是,我認爲這需要通過構建具有多個參數的等大小的準備語句來手動完成。 (保持變化小數)。 – eckes

+0

@eckes所以我想我會將他們批量分成20個左右的組,做一個本地選擇其中的id(id1,id2,...,id20),然後調查返回的結構中返回的原始列表的id 。 –

+0

是的,所以110個結果將是15次往返(5 x 20 + 10 x 1),只有2個不同的語句需要解析。或者你可以有100,10和1,這取決於通常檢查的物品數量範圍。我不確定Hibernate是否有這個幫手。 – eckes

回答

1

我肯定會推薦本機查詢,如意見建議。

但是,我不打擾他們,但是,鑑於你所談論的數字。 Postgres應該能夠處理具有500個元素且沒有問題的IN子句。我有編程生成的查詢與更多的項目比執行正常。

這樣你也只有一次往返旅程,假設合適的索引到位,真的應該在次秒內完成。

+0

我這樣做,遍歷外部標識符,將它們添加到一個集合中,然後查詢'select * from id where(...)'中的項目,並返回匹配的id列表。然後,我再次遍歷原始的一組外部項目,並且對於結果集中的每個項目,我做了一個'session.load()',並且對於不在結果集中的每個項目,我創建了新的並保存了所有內容。現在這個操作需要2-3秒,這對於一個web應用來說更合理。 –

相關問題