You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Criteria API直接查询关联的List<Maintenance>并支持排序

直接用Criteria API查询指定Guest关联的Maintenance列表并支持SQL排序

要直接通过Criteria API获取指定Guest关联的List<Maintenance>并支持SQL层面的动态排序,你可以跳过查询完整Guest对象的步骤,直接构建针对Maintenance的查询,通过关联Guest过滤目标数据,同时灵活添加排序条件。以下是具体实现方案:

基础实现(按Maintenance自身字段排序)

这种方式适用于根据Maintenance实体自身的属性排序,比如按ID、创建时间等:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// 直接创建返回Maintenance的查询
CriteriaQuery<Maintenance> cq = cb.createQuery(Maintenance.class);
Root<Maintenance> maintenanceRoot = cq.from(Maintenance.class);

// 关联到Guest表,过滤指定Guest的ID
Join<Maintenance, Guest> guestJoin = maintenanceRoot.join("guests", JoinType.INNER);
cq.where(cb.equal(guestJoin.get("id"), guestId));

// 添加排序条件:示例为按Maintenance的createTime字段升序
cq.orderBy(cb.asc(maintenanceRoot.get("createTime")));

// 去重:多对多关联查询会产生重复结果,必须添加
cq.distinct(true);

TypedQuery<Maintenance> query = entityManager.createQuery(cq);
List<Maintenance> resultList = query.getResultList();

按中间表字段排序(如order_timestamp)

如果需要根据中间表guest_2_maintenance的字段(比如order_timestamp)排序,需要显式通过关联操作访问中间表的字段:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Maintenance> cq = cb.createQuery(Maintenance.class);
Root<Maintenance> maintenanceRoot = cq.from(Maintenance.class);

// 关联到中间表(通过Maintenance与Guest的多对多关联)
Join<Maintenance, Object> joinTable = maintenanceRoot.join("guests", JoinType.INNER);

// 过滤指定Guest的ID
cq.where(cb.equal(joinTable.get("guest_id"), guestId));

// 按中间表的order_timestamp降序排序
cq.orderBy(cb.desc(joinTable.get("order_timestamp")));

// 去重避免重复结果
cq.distinct(true);

TypedQuery<Maintenance> query = entityManager.createQuery(cq);
List<Maintenance> resultList = query.getResultList();

从Guest出发的实现方式

你也可以从Guest表开始关联,最终选择Maintenance作为查询结果:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Maintenance> cq = cb.createQuery(Maintenance.class);
Root<Guest> guestRoot = cq.from(Guest.class);

// 关联到Maintenance表
Join<Guest, Maintenance> maintenanceJoin = guestRoot.join("orderedMaintenances", JoinType.INNER);

// 过滤指定Guest的ID
cq.where(cb.equal(guestRoot.get("id"), guestId));

// 按中间表的order_timestamp排序
Join<Guest, Object> joinTable = guestRoot.join("orderedMaintenances", JoinType.INNER);
cq.orderBy(cb.desc(joinTable.get("order_timestamp")));

// 明确选择Maintenance作为返回结果
cq.select(maintenanceJoin);

// 去重
cq.distinct(true);

TypedQuery<Maintenance> query = entityManager.createQuery(cq);
List<Maintenance> resultList = query.getResultList();

关键注意事项

  • 去重操作:多对多关联查询会生成重复的Maintenance记录,必须添加cq.distinct(true)保证结果唯一性。
  • 动态排序:你可以根据业务需求动态替换排序字段和排序方向,比如通过参数判断是按order_timestamp还是Maintenance的其他字段排序,完全在SQL层面完成,性能优于内存中的Comparator排序。
  • 关联类型:示例中使用JoinType.INNER,如果需要包含没有关联Maintenance的Guest(但这里是查询Guest的Maintenance,所以INNER更合适),可以根据需求改为LEFT。

内容的提问来源于stack exchange,提问作者cognosce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 12:06:32