如何将指定左连接SQL转换为JPA Criteria查询
JPA Criteria 实现对应查询逻辑
针对@ElementCollection标注的集合字段,直接通过实体类的集合属性做左关联即可,JPA会自动维护实体表和集合映射表的关联关系,不需要手动指定n.id = ns.n_id的关联条件。
完整实现代码如下:
// 已完成初始化的基础代码 CriteriaBuilder criteriaBuilder = getCurrentSession().getCriteriaBuilder(); CriteriaQuery<N> criteria = criteriaBuilder.createQuery(N.class); Root<N> news = criteria.from(N.class); // 1. 左关联@ElementCollection标注的集合字段,将"nodeIds"替换为你实体类中该集合的实际属性名即可 Join<N, String> nsJoin = news.join("nodeIds", JoinType.LEFT); // 2. 拼接查询条件 // 条件1:n.public = true Predicate isPublic = criteriaBuilder.isTrue(news.get("public")); // 条件2:左连接后ns表无匹配记录,对应SQL中ns.n_id is null Predicate nsIsNull = criteriaBuilder.isNull(nsJoin); // 条件3:ns.node_id在指定值列表中 Predicate nodeIdIn = nsJoin.in("25", "1407114"); // 组合or逻辑:无匹配集合记录 或 集合值命中指定列表 Predicate nsCondition = criteriaBuilder.or(nsIsNull, nodeIdIn); // 组合最终where条件 criteria.where(criteriaBuilder.and(isPublic, nsCondition)); // 加distinct去重,避免一对多左连接产生重复的N实体记录 criteria.select(news).distinct(true); // 执行查询获取结果 List<N> result = getCurrentSession().createQuery(criteria).getResultList();
关键说明
news.join("nodeIds", JoinType.LEFT)中的"nodeIds"需要替换为N实体类里被@ElementCollection注解标注的集合属性的实际字段名,不要直接写映射表名ns,JPA会自动根据注解配置关联到ns表,手动追加n.id = ns.n_id关联条件反而会造成SQL冗余甚至报错。- 必须追加
distinct(true):左连接属于一对多关联,单个N实体如果匹配到多条ns表记录时会返回重复的N对象,加去重后才能得到和原生SQL一致的不重复结果。 - 如果
node_id字段是数值类型,把in条件里的字符串替换为对应数值即可,例如nsJoin.in(25, 1407114)。
内容的提问来源于stack exchange,提问作者temp_temp
相关产品推荐
相关产品推荐

