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

如何将含嵌套子查询的关联查询转换为Spring JPA实体?

Spring JPA实现含子查询的关联查询

当然可以,Spring JPA(依托Hibernate等实现)支持在关联操作中嵌入子查询,不管是JPQL、Criteria API还是原生SQL注解都能实现,下面是针对你给出的SQL的几种实现方案:

1. 使用JPQL + @Query注解

假设对应的实体类为TableM、TableMP、TableP,字段与数据库列映射正确(如fstNm对应FST_NM,dob对应DOB等),可以直接在JPQL的JOIN中嵌入子查询:

@Repository
public interface TableMRepository extends JpaRepository<TableM, Long> {

    @Query("SELECT DISTINCT m FROM TableM m " +
           "JOIN (SELECT DISTINCT mp FROM TableMP mp WHERE mp.fstNm = :fstNm AND mp.dob = :dob) mp " +
           "ON m.id = mp.id " +
           "JOIN TableP p ON p.id = mp.id AND p.list IN :list")
    List<TableM> findDistinctMByConditions(@Param("fstNm") String fstNm, 
                                           @Param("dob") LocalDate dob, 
                                           @Param("list") List<String> list);
}

注意:部分JPA提供商对JPQL中JOIN子查询的支持略有差异,若遇到兼容性问题,可将子查询转为WHERE条件中的IN子句。

2. 使用原生SQL + @Query注解

直接复用你的原生SQL,通过nativeQuery=true标记为原生查询:

@Repository
public interface TableMRepository extends JpaRepository<TableM, Long> {

    @Query(value = "SELECT DISTINCT m.* " +
                   "FROM tablem m " +
                   "JOIN (SELECT DISTINCT * FROM tablemp WHERE FST_NM = :fstNm AND DOB = :dob) AS mp " +
                   "ON m.ID = mp.ID " +
                   "JOIN tablep p ON p.ID = mp.ID AND p.LIST IN (:list)",
           nativeQuery = true)
    List<TableM> findDistinctMByNativeQuery(@Param("fstNm") String fstNm, 
                                            @Param("dob") String dob, 
                                            @Param("list") List<String> list);
}

提示:日期参数可根据数据库类型选择传入LocalDate或格式化后的字符串。

3. 使用Criteria API动态构建

如果需要动态调整查询条件,适合用Criteria API实现:

@Repository
public class TableMCustomRepository {

    @PersistenceContext
    private EntityManager entityManager;

    public List<TableM> findDistinctMWithCriteria(String fstNm, LocalDate dob, List<String> list) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<TableM> query = cb.createQuery(TableM.class);
        Root<TableM> mRoot = query.from(TableM.class);

        // 构建子查询:筛选符合条件的TableMP的ID集合
        Subquery<Long> mpSubquery = query.subquery(Long.class);
        Root<TableMP> mpRoot = mpSubquery.from(TableMP.class);
        mpSubquery.select(mpRoot.get("id"))
                  .distinct(true)
                  .where(cb.equal(mpRoot.get("fstNm"), fstNm),
                         cb.equal(mpRoot.get("dob"), dob));

        // 关联TableP并添加条件
        Join<TableM, TableP> pJoin = mRoot.join("tableP", JoinType.INNER);
        query.distinct(true)
             .select(mRoot)
             .where(cb.in(mRoot.get("id")).value(mpSubquery),
                    pJoin.get("list").in(list));

        return entityManager.createQuery(query).getResultList();
    }
}

注意:需确保实体类之间的关联关系已正确映射(如TableM与TableP的id关联),若没有预设关联,可调整为交叉关联或直接通过ID匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:27:38