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

如何使用JPA Criteria Builder实现多表左连接查询?

实现JPA Criteria Builder对应SQL的步骤

你已经成功创建了Alert到MarkerGroup的左连接,接下来只需要完成剩余的关联、条件添加和投影配置即可,具体步骤如下:

1. 关联Marker表

从已有的markerGroupJoin出发,左连接到Marker实体(对应SQL里的LEFT JOIN marker m ON mg.id = m.marker_group_id)。假设你的Marker实体中,关联MarkerGroup的字段名为markerGroup,代码如下:

Join<MarkerGroup, Marker> markerJoin = markerGroupJoin.join("markerGroup", JoinType.LEFT);
// 若MarkerGroup是通过集合关联Marker(比如MarkerGroup有List<Marker> markers字段),则用joinCollection:
// Join<MarkerGroup, Marker> markerJoin = markerGroupJoin.joinCollection("markers", JoinType.LEFT);

注意:这里的字段名要和你实体类中定义的关联属性名一致,不是数据库表的物理字段名。

2. 添加查询条件

接下来添加经纬度的过滤条件,对应SQL里的where m.latitude = '32.985173502462686' AND m.longitude='-96.89707056619227':

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> query = cb.createTupleQuery();

Root<Alert> root = query.from(Alert.class);
Join<Alert, MarkerGroup> markerGroupJoin = root.join("markerGroup", JoinType.LEFT);
Join<MarkerGroup, Marker> markerJoin = markerGroupJoin.join("markerGroup", JoinType.LEFT); // 需匹配你的实体关联字段

// 构造过滤条件
Predicate latitudePredicate = cb.equal(markerJoin.get("latitude"), "32.985173502462686");
Predicate longitudePredicate = cb.equal(markerJoin.get("longitude"), "-96.89707056619227");
query.where(cb.and(latitudePredicate, longitudePredicate));

3. 配置投影字段

因为你只需要查询a.id, a.marker_group_id, a.name,所以需要指定要返回的字段:

// 选择Alert的id、MarkerGroup的id(对应marker_group_id)、Alert的name
query.multiselect(
    root.get("id"),
    markerGroupJoin.get("id"),
    root.get("name")
);

4. 执行查询并获取结果

最后执行查询,处理返回的结果:

List<Tuple> results = entityManager.createQuery(query).getResultList();

// 遍历结果示例
for (Tuple tuple : results) {
    Long alertId = tuple.get(root.get("id"), Long.class);
    Long markerGroupId = tuple.get(markerGroupJoin.get("id"), Long.class);
    String alertName = tuple.get(root.get("name"), String.class);
    // 后续业务逻辑处理
}

补充说明

  • 如果你的项目中使用DTO接收结果,可以用cb.construct()代替multiselect,比如创建一个AlertProjectionDTO包含id、markerGroupId、name字段:
CriteriaQuery<AlertProjectionDTO> query = cb.createQuery(AlertProjectionDTO.class);
// ... 关联和条件部分同上
query.select(cb.construct(AlertProjectionDTO.class,
    root.get("id"),
    markerGroupJoin.get("id"),
    root.get("name")
));
List<AlertProjectionDTO> results = entityManager.createQuery(query).getResultList();
  • 注意经纬度类型:如果数据库中是数值类型(比如DECIMAL或DOUBLE),不要用字符串传入,应该用对应的数值类型(比如Double),避免类型转换问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:15:25