2015-05-20 112 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应用来说更合理。 –

相关问题