Java 对内存中的集合运行JPQL查询

Java 对内存中的集合运行JPQL查询,java,jpa,drools,jpql,in-memory-database,Java,Jpa,Drools,Jpql,In Memory Database,是否有一个Java库允许我对基本Java集合执行JPQL查询,有效地将该集合视为内存中的数据库 我目前正在为每个查询变量编写自定义代码,这很容易出错,也很难维护。由于需要与其他代码交互操作,我无法从集合切换到真正的内存中数据库(如HSQLDB) 我可以想出两个变通办法。因为这些集合是暂时的,并且经常并行处理,所以这些变通方法似乎会增加太多的开销(但请随意说服我)。这些是: 每次我需要对集合运行JPQL查询时,都要建立一个临时内存数据库,从集合中填充它,然后对数据库运行查询。-我相信这会带来的开销

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

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

我可以想出两个变通办法。因为这些集合是暂时的,并且经常并行处理,所以这些变通方法似乎会增加太多的开销(但请随意说服我)。这些是:

  • 每次我需要对集合运行JPQL查询时,都要建立一个临时内存数据库,从集合中填充它,然后对数据库运行查询。-我相信这会带来的开销并不是因为我试图解决的问题
  • 类似于#1,但保留内存中的数据库以减少开销。-集合的暂时性意味着,如果我为每个集合保留一个数据库,这并不比#1好多少。这些查询的并行性使得在不同的集合查询中重用相同的内存中数据库实例非常重要

  • 编辑:

    下面是确切的用例:

    我们使用Drools在服务器上更改数据时对其执行验证。我们的验证规则要求将大量支持数据加载到知识会话中

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

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

    这方面的缺点是设计必须考虑到规则的更改和在以后的生产系统中的添加;规则更改可能会更改验证所需的数据,因此数据加载机制必须同样灵活

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

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


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

    如果您想尝试DataNucleus JPA做这种性质的事情,您需要掌握他们的内部查询类,我认为,类似于

    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");
    

    我只在JDOAPI和候选集合中使用过它,但应该可以使用。

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