如何通过@IndexColumn 中的数字选择集合中的第 n 个元素?

Posted

技术标签:

【中文标题】如何通过@IndexColumn 中的数字选择集合中的第 n 个元素?【英文标题】:How do I select the nth element in a Collection by the number in an @IndexColumn? 【发布时间】:2011-04-25 19:38:20 【问题描述】:

我有一个 ItemEntity 类,它有一个 ImageEntity 的集合。鉴于它在集合中的索引,我希望能够获取特定的 ImageEntity。例如,对于具有 10 个 ImageEntity 的 ItemEntity,我希望在尽可能少的数据库命中中使用第 4 个 ImageEntity。

我已经阅读了 Hibernate In Action 并在 Google 上搜索过,但我能找到的每篇文档都非常简洁地描述了 @IndexColumn,没有详细的使用示例。

我可以使用 item.getImages() 来获取 List,然后在其上调用 .get(4)。但这涉及将整个集合加载到内存中以便能够对其调用 get() .

我想做的是这样的:

int itemId = 111; // 我要为其获取图像的项目的 ID int wantImageNum = 4; // 我想要的图像的索引,在项目的列表中 imageId = .. 以某种方式获取第 4 个 ImageEntity .. 的 id; ImageEntity img = session.load(ImageEntity.class, imageId);

我使用@IndexColumn 让 Hibernate 管理集合中 ImageEntity 的排序,即:

公共类 ItemEntity ... @ManyToMany(cascade=CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, fetch=FetchType.LAZY) @JoinTable(name = "ItemImages", 加入列 = @JoinColumn(name="item_id", referencedColumnName="id") // 这个类中的id , inverseJoinColumns = @JoinColumn(name="image_id") // ImageEntity 中的 id ) @org.hibernate.annotations.IndexColumn(name="idx​​", base=1) 私有列表图像 = new ArrayList();

因此,有一个如下所示的“连接表”:

表项目图像( item_id image_id 编号 )

我可以用普通的 SQL 做一些非常肮脏的事情,即

从 ItemImages 中选择 image_id,其中 item_id = :itemId 和 idx = :wantImageNum;

这显然是可怕的。我无法使用 HQL 或 Criteria 查询来实现类似的技巧,因为 ItemImages 不是映射实体,它是由 Hibernate 管理的连接表。

【问题讨论】:

【参考方案1】:

index() HQL 函数正是您要寻找的:

select image
from ItemEntity item
join item.images image
where index(image) = 4
and item.id = 111

它在 JPA 2.0 中也被标准化为 INDEX。来自规范:

4.6.17.2.2 算术函数

functions_returning_numerics::=
        ABS(simple_arithmetic_expression) |
        SQRT(simple_arithmetic_expression) |
        MOD(simple_arithmetic_expression, simple_arithmetic_expression) |
        SIZE(collection_valued_path_expression) |
        INDEX(identification_variable)

(...)

INDEX 函数返回一个 对应的整数值 它的论点在有序中的位置 列表。 INDEX 函数只能是 应用于识别变量 表示订单的类型 列已指定。

在以下示例中, studentWaitlist 是一个列表 订单列有的学生 已指定:

SELECT w.name
FROM Course c JOIN c.studentWaitlist w
WHERE c.name = ‘Calculus’
AND INDEX(w) = 0

参考文献

Hibernate 核心参考指南 14.10. Expressions JPA 2.0 规范 第 4.6.17.2.2 节算术函数

【讨论】:

太好了,谢谢帕斯卡,它以一种很好的面向对象的方式回答了这个问题(我不需要获取 image_id 然后基于它获取对象)。我无法找到 Hibernate 文档的那一部分。如果只有 @IndexColumn 引用了该部分,其中描述了 index() 和相关函数。看到类似“from Order order where order.items[0].id = 1234”这样的结构也很有趣。 @Nick 不客气。没错,将特定注释链接到相关查询语言功能并不总是那么容易。这可能是文档(和规范)中可以改进的一个领域。是的,“类似数组”的语法也很有趣。

以上是关于如何通过@IndexColumn 中的数字选择集合中的第 n 个元素?的主要内容,如果未能解决你的问题,请参考以下文章

使用 IndexColumn 从 ManyToMany 中删除

如何使函数与Scala中的任何数字类型的集合一起使用

进行查询后,如何通过 Collection 中的 where 子句获取选择的模型

如何通过 SQL 查询选择集合数据?

如何从数据框中删除 n并将数据移至新行

如何将一个集合分成两个子集,以使两个集合中数字之和之间的差异最小?