8

我们有一个系统通过调用另一个系统上的接口来执行“粗略搜索”,该接口返回一组 Java 对象。一旦我们收到搜索结果,我需要能够根据描述属性状态的某些标准进一步过滤生成的 Java 对象(例如,从初始对象返回 xy > z && ab == c 的所有对象)。

每次用于过滤对象集的标准部分是用户可配置的,我的意思是用户将能够选择要匹配的值和范围,但他们可以从中选择的属性将是一个固定的集合。

对于每次搜索,数据集可能包含 <= 10,000 个对象。搜索将由应用程序用户群手动执行,每天可能不超过 2000 次(大约)。值得一提的是,结果集中的所有对象都是已知的域对象类,它们具有描述其结构和关系的 Hibernate 和 JPA 注释。

可能的解决方案

在我的脑海中,我能想到 3 种方法:

  1. 对于每次搜索,我们的数据库中都会保留初始结果集对象,然后使用 Hibernate 使用更细粒度的条件重新查询它们。
  2. 使用内存数据库(例如 hsqldb?)来查询和优化初始结果集。
  3. 编写一些自定义代码来迭代初始结果集并提取所需的记录。

选项1

选项 1 似乎涉及通过网络到物理数据库 (Oracle 10g) 的大量往返,这可能会导致大量网络和磁盘活动。它还需要将每次搜索的结果与其他结果集隔离,以确保不同的搜索不会相互干扰。

选项 2

选项 2 原则上似乎是一个好主意,因为它允许我在内存中进行更精细的查询,并且不需要保留结果数据,这些数据只有在搜索完成后才会被丢弃。直觉是,这也可能非常高效,但可能会导致更大的内存开销(这很好,因为我们可以在 JVM 获得的内存量上非常灵活)。

选项 3

选项 3 可能非常高效,但我想避免这种情况,因为我们编写的任何代码都需要如此仔细的测试,以至于实现足够灵活和健壮的东西所花费的时间可能会令人望而却步。


我没有时间对所有 3 个想法进行原型制作,所以我正在寻找人们可能对上述 3 个选项的评论,以及我没有考虑过的任何其他想法,以帮助我决定哪个想法可能最合适。我目前倾向于选项 2(在内存数据库中),因此也很想听听有在内存中查询 POJO 经验的人的意见。

希望我已经足够详细地描述了这种情况,但不要犹豫,询问是否需要任何进一步的信息才能更好地理解这种情况。

干杯,

埃德

4

4 回答 4

1

选项 1 和 2 非常兼容:通过实现一个,您可以通过简单重新配置 persistence.xml 将其替换为另一个(假设内存数据库与 JPA 兼容,例如 JavaDB、Derby 等)。

选项 3 是重新实现第三方软件(数据库)和您自己的代码(现有 JPA 实体)。您还列出了它的优点作为关注点。在您的情况下,这显然是一个不太可行的选择。我也想不出其他任何东西来推广选项 3。

考虑到用例及其时间跨度,内存数据库似乎更适合。如果需求演变为不那么短暂的需求,那么您可以切换到 Oracle。

于 2010-05-19T05:16:23.767 回答
1

如果您的表达式不太复杂,您可以使用表达式语言来评估对 Java 对象 (POJO) 的字符串查询。我可以推荐 MVEL http://mvel.codehaus.org

这个想法是将对象放入 MVEL 上下文中。然后您提供根据 MVEL 简单表示法编写的字符串查询,最后评估表达式。

取自 MVEL 网站的示例:

Map vars = new HashMap();
vars.put("x", new Integer(5));
vars.put("y", new Integer(10));

Integer result = (Integer) MVEL.eval("x * y", vars);
assert result.intValue() == 50;  // Mind the JDK 1.4 compatible code :)

通常,表达式语言支持遍历您的对象图(集合)并以 JSP EL 样式(点表示法)访问成员。

另外,我可以建议查看 OGNL(谷歌它,我不能添加多个链接)

于 2010-05-21T12:45:07.067 回答
0

精炼标准有多复杂?如果大多数都很简单,我很想从选项(3)开始,但要确保它被封装在一个合适的接口后面,这样如果你遇到一些过于复杂或效率低下而无法自己编写代码的东西可以在此时切换到内存数据库(对于所有查询批发,或者如果在设置临时表时存在开销,则只针对复杂查询)。

于 2010-05-18T11:20:05.060 回答
0

选项 2 似乎不错 - 因为您可以根据需要在 1 和 2 之间切换。3 在未来的数据大小问题方面也受到限制。查询对象意味着对存储和查询代码结构的更大依赖。

可能最好包含一些缓存机制(ehcache/memcache)以及选项 2 的使用,然后进行分析以检查性能差异。

于 2010-05-19T08:11:05.293 回答