【问题标题】:JPA 2.0: Batch query, safe and performant?JPA 2.0:批量查询,安全又高效?
【发布时间】:2012-02-29 19:36:53
【问题描述】:

我正在寻找一个 JPA 解决方案(独立于供应商)来批量执行查询。面临的挑战是使这个性能和线程安全。

查询示例:

Query query = em.createQuery("select e from Entity e where e.property in :list");

列表是大小在 1 到 385000 之间的集合。因此,需要批处理此查询。

最初的幼稚方法是从原始列表中获取子列表并循环直到完成。这是安全且运行良好的,只是它性能不佳。

第二种方法是将列表中的所有内容加载到临时表(永久存在,但用作临时表),然后使用原始查询并与临时表连接。这绝对是高性能的,但不是线程安全的,因为我需要在每次批处理后清除临时表,并且临时表中没有任何线程 ID 或类似的东西,它非常不安全(目前)。

我非常感谢您提出的建议,以找到一种高效且安全的方式来解决此问题。

谢谢

【问题讨论】:

  • 独立于供应商意味着更改您的查询(以添加“SELECT e”),因为这不是您提供的 JPQL。发布实体类。
  • 谢谢大家。稍微弄乱了查询,将对其进行修改以确保它看起来正确

标签: jpa jpa-2.0


【解决方案1】:

首先,查询不是有效的 JPQL,因为它没有 select 子句。

其次,应该是where e.property in (:list)

您填充临时表的策略对我来说看起来不错。你可以让它包含一个额外的 uuid 列,并在每次你想要执行这样的查询时生成一个新的 UUID:

  • 生成 UUID
  • 将列表的所有元素插入表中,并将uuid列设置为生成的UUID
  • 执行select e from Entity e, TempEntity temp where e.property = temp.property and temp.uuid = :uuid等查询
  • 执行查询以删除临时表中的所有行(并非绝对必要):delete from TempEntity temp where temp.uuid :uuid

【讨论】:

  • 非常感谢。我刚刚想到了 UUID 的事情并得到了你的验证:)
  • 很确定它应该是“in :list”,“in (:list)”是一个包含一个元素的列表,即“in (:arg1, :ag2)”是一个包含两个元素的列表, "in (:arg1)" => "in (4)" 如果 arg 为 4。
  • @James:你是对的。我习惯了 Hibernate,直到最近,括号在 Hibernate JPQL 查询中是强制性的。见hibernate.onjira.com/browse/HHH-5126
猜你喜欢
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
相关资源
最近更新 更多