如何在Java中查询对象集合(类似于Criteria / SQL)?

时间:2020-03-06 14:21:48  来源:igfitidea点击:

假设我们有数百个内存中对象的集合,并且需要查询此List以返回与某些SQL或者Criteria(如查询)匹配的对象。例如,我们可能有一个"汽车"对象列表,并且想要退回1960年代制造的所有汽车,并以AZ开头的车牌按汽车型号名称排序。

我知道JoSQL,是否有人使用过,或者对其他/本地解决方案有任何经验?

解决方案

我将使用一个比较器,该比较器使用年份范围和车牌图案作为输入参数。然后只需遍历集合并复制匹配的对象。我们可能最终会用这种方法制作一整套定制比较器。

如果需要单个具体匹配,则可以让该类实现Comparator,然后创建一个包含所有哈希字段的独立对象,并使用它返回匹配的索引。当我们想在集合中找到多个(潜在的)对象时,我们将不得不转向像JoSQL这样的库(在我使用过的琐碎情况下,它工作得很好)。

通常,我倾向于将Derby甚至嵌入到我的小型应用程序中,使用Hibernate批注定义我的模型类,并让Hibernate处理缓存方案以使一切保持快速。

我已经在生产应用程序中使用过Apache Commons JXPath。它允许我们将XPath表达式应用于Java中的对象图。

比较器选项还不错,特别是如果我们使用匿名类(以免在项目中创建冗余类),但是最终当我们查看比较流程时,它就像我们自己遍历整个集合一样,确切指定匹配项的条件:

if (Car car : cars) {
    if (1959 < car.getYear() && 1970 > car.getYear() &&
            car.getLicense().startsWith("AZ")) {
        result.add(car);
    }
}

然后是排序...在背面可能会很痛苦,但是幸运的是,有一个类Collections及其sort方法,其中一个接受了一个" Comparator" ...

继续使用"比较器"主题,我们可能还想看看Google Collections API。特别是,它们具有一个称为Predicate的接口,该接口的作用类似于"比较器",因为它是可由Sets.filter等过滤方法使用的简单接口。它们包括一大堆复合谓词实现,用于执行AND,OR等。

根据数据集的大小,使用这种方法可能比使用SQL或者外部关系数据库方法更有意义。