【问题标题】:Run JPQL query against in-memory collection针对内存中的集合运行 JPQL 查询
【发布时间】:2015-08-13 10:20:38
【问题描述】:

是否有 Java 库允许我对基本 Java 集合执行 JPQL 查询,有效地将集合视为内存数据库?

我目前正在为每个查询变体编写自定义代码,该代码容易出错且难以维护。由于需要与其他代码互操作,我无法从集合切换到真正的内存数据库,如 HSQLDB。

我能想到两种解决方法。因为这些集合是瞬态的并且经常并行处理,所以这些变通方法似乎会增加太多开销(但请随意说服我)。它们是:

  1. 每次我需要对集​​合运行 JPQL 查询时,建立一个临时内存数据库,从集合中填充它,然后针对数据库运行查询。 - 我认为这会带来的开销与我要解决的问题不相符。
  2. 与 #1 类似,但保留内存数据库以减少开销。 - 集合的瞬态性质意味着如果我为每个集合保留一个数据库,这并不比 #1 好多少。这些查询的并行特性使得在不同的集合查询中重用相同的内存数据库实例变得不简单。

编辑:

这是确切的用例:

当数据在我们的服务器上发生变化时,我们正在使用 Drools 对数据执行验证。我们的验证规则需要将大量支持数据加载到知识会话中。

为简单起见,我们尝试在每次需要时都建立一个知识会话,这样我们就不必担心过时的数据,但是这样做的时间性能是不可接受的。

我们现在切换到与数据库保持同步的知识会话。知识会话最初是在第一次访问时填充的。 JPA 回调侦听器将实体添加记录到集合中,并且这些实体将在下次机会时合并到知识会话中如果它们适用

其中的问题是设计必须允许以后在生产系统上更改和添加规则;规则更改可能会更改验证所需的数据,因此数据加载机制必须同样灵活。

从我们的第一次尝试开始,我们就已经有了一种机制,规则通过 JPQL 语句定义应该加载哪些数据,然后我们执行这些 JPQL 语句来初始填充知识会话。

我现在利用这些相同的 JPQL 语句来确定应该将来自 JPA 回调侦听器的哪些实体添加到知识会话中。为此,我正在编写代码来解释此 JPQL,并将 where 子句过滤器应用于来自 JPA 回调侦听器的实体。我更愿意使用第三方库来为我执行此操作。

如果您认为我们应该以完全不同的方式解决这个问题,请随时提出更改建议。设计很复杂,但不幸的是,其中大部分是由客户需求驱动的,无法避免。

【问题讨论】:

  • 我永远不会考虑使用这些方法中的任何一种。如果您使用 Java 8,则在创建 查询 时使用流 api 将非常有效且不易出错。尽管如此,提供您想要/需要的样本可以帮助我们提供更好的替代方案来解决这个问题。
  • 我不确定这样做的目的。如果是测试,那么使用 DBUnit 和一些内存数据库,它应该足够快速和高效,而不影响生产代码。如果不是测试,请多解释一下用例...
  • 这是您要问的问题吗? stackoverflow.com/questions/1217228/…
  • DataNucleus JPA 允许这样的事情,因为它也支持 JDO 并且 JDO 查询需要它作为一个特性
  • @LuiggiMendoza 不幸的是,我们被困在 Java 6 上,但我认为流 API 仍然会给我留下需要将现有 JPQL 转换为应用等效过滤器的 Java 代码的问题。

标签: java jpa drools jpql in-memory-database


【解决方案1】:

如果你想尝试 DataNucleus JPA 来做这种性质的事情,你需要掌握他们的内部 Query 类,我认为是这样的

Query q = em.createQuery(...)
org.datanucleus.store.query.Query dnq = ((org.datanucleus.api.jpa.JPAQuery)q).getInternalQuery();
dnq.setCandidates(myCollectionOfCandidates);
...
List results = q.getResultList();

你可能还需要

q.setHint("datanucleus.query.evaluateInMemory","true");

我只将它用于带有候选集合的 JDO API,但应该可以使用。

【讨论】:

    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    相关资源
    最近更新 更多