如何使用Hibernate实现两个无关实体关联查询,获取收藏的Screen
Hibernate实现获取所有被收藏Screen的几种方式
嘿,既然你已经用SQL子查询搞定了需求,那咱们来看看几种更贴合Hibernate生态的实现方式,不管是用JPQL、Criteria API还是实体关联都能做到:
1. 用JPQL子查询(最贴近你现有SQL的写法)
JPQL支持和SQL类似的子查询语法,直接把你的SQL逻辑转成面向实体的查询就行,代码示例如下:
// 在你的ScreenRepository或者EntityManager使用场景中 String jpql = "SELECT s FROM Screen s WHERE s.screenId IN (SELECT fs.screenId FROM FavoriteScreen fs)"; TypedQuery<Screen> query = entityManager.createQuery(jpql, Screen.class); List<Screen> favoriteScreens = query.getResultList();
这种写法几乎和你原来的SQL逻辑一一对应,上手快,可读性也强。
2. 用Hibernate Criteria API(类型安全的动态查询)
如果你的查询条件可能需要动态调整,用Criteria API会更合适,它是类型安全的,能避免字符串拼接的错误:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Screen> cq = cb.createQuery(Screen.class); Root<Screen> screenRoot = cq.from(Screen.class); // 构建子查询:获取所有FavoriteScreen中的screenId Subquery<Long> subquery = cq.subquery(Long.class); Root<FavoriteScreen> fsRoot = subquery.from(FavoriteScreen.class); subquery.select(fsRoot.get("screenId")); // 主查询筛选:screenId在子查询结果中 cq.select(screenRoot).where(cb.in(screenRoot.get("screenId")).value(subquery)); List<Screen> favoriteScreens = entityManager.createQuery(cq).getResultList();
3. 利用实体关联直接查询(最简洁的方式,前提是正确映射关联)
如果你的FavoriteScreen实体已经和Screen做了关联映射(比如用@ManyToOne),那可以直接通过关联关系查询,根本不需要子查询:
首先确保FavoriteScreen里的关联字段配置正确:
@Entity public class FavoriteScreen { // 其他字段... @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "screen_id") // 对应数据库中的外键字段 private Screen screen; // getter和setter... }
然后直接查询所有FavoriteScreen关联的Screen:
String jpql = "SELECT DISTINCT fs.screen FROM FavoriteScreen fs"; TypedQuery<Screen> query = entityManager.createQuery(jpql, Screen.class); List<Screen> favoriteScreens = query.getResultList();
这里加DISTINCT是为了避免同一个Screen被多次收藏时出现重复结果,根据你的业务需求可以选择是否添加。
这几种方式都能实现你要的效果,你可以根据自己的实体映射情况和查询复杂度来选~
内容的提问来源于stack exchange,提问作者Mouldi Ouni
相关产品推荐
相关产品推荐

