JPQL / HQL - 是否可以通过提供ID列表来指定订单?

时间:2011-10-02 14:19:13

标签: java jpa playframework hql

(注意:我正在使用Play!框架,它使用Hibernate作为JPA实现。)

我有一个ID列表,我想通过保留我的ID列表中使用的顺序从数据库中获取项目。

假设我的名单是:444,222,333,111

我希望JPQL / HQL首先返回id为#444的Item,然后返回id为#222的Item等。

我尝试过类似的事情:

id in (444,222,333,111) order by id=444 DESC, id=222 DESC, id=333 DESC, id=111 DESC

但它似乎不起作用。

是否有可能或者我必须忘记“订购依据”部分并在退回后手动重新订购商品?

4 个答案:

答案 0 :(得分:1)

如果没有“自然”订单,那么您可能需要手动订购;您可能能够依赖数据库排序,具体取决于数据库和查询结构,但IMO存在风险。

从好的方面来说,除非你有大量的对象,否则开销很小。

答案 1 :(得分:0)

这个特殊情况可以使用ORDER BY id DESC轻松处理,但我猜它只是一个选择不当的例子。

除非你能找到一种利用SQL来实现它的方法,否则我说这是不可能的。

您应该有一个持久层来将数据库中的对象映射到Java(您不应该将ResultSet从持久层传递出去)。在那里做这件事是微不足道的。

答案 2 :(得分:0)

我认为你必须用Java对项目进行排序:

public void sortItems(List<Item> items, final List<Long> ids) {
    Collections.sort(items, new Comparator<Item>() {
        @Override
        public int compare(Item i1, Item i2) {
            int index1 = ids.indexOf(i1.getId());
            int index2 = ids.indexOf(i2.getId());
            return Integer.valueOf(index1).compareTo(Integer.valueOf(index2));
        }
    });
}

答案 3 :(得分:0)

即使是很老的问题也会在很久以后再次问到。我使用映射解决了这个问题:

@Override
public List<MyItem> fetch(List<Long> ids) {
    // Create an identity map using the generic fetch. Rows are returned, but not necessarily in the same order
    Map<Long, MyItem> resultMap = super.fetch(ids).stream().collect(Collectors.toMap(MyItem::getId, Function.identity()));
    // Now return the rows in the same order as the ids, using the map.
    return ids.stream().map(id -> resultMap.get(id)).collect(Collectors.toList());
}