如何在Hibernate中从用户与广告的多对多关联表查询数据
嘿,你已经把User和Advert的多对多关联配置得很清楚了,关联表是faved_ads对吧?下面我给你几种在Hibernate里查询这个关联表数据的常用方法,你可以根据场景选合适的:
方法1:通过实体关联属性直接查询
这是最简单的方式,因为你已经配置了双向多对多关联,直接从实体对象获取关联数据就行:
// 获取ID为1的广告的所有收藏用户 Advert advert = entityManager.find(Advert.class, 1L); List<User> favouriters = advert.getFavouriters(); // 获取ID为2的用户的所有收藏广告 User user = entityManager.find(User.class, 2L); List<Advert> favourites = user.getFavourites();
这种方法适合你已经拿到实体对象,只需要获取它的关联数据的场景,Hibernate会自动帮你处理关联表的查询。
方法2:使用JPQL灵活查询
如果需要带条件的查询(比如筛选特定用户的收藏、统计热门广告),用JPQL就很方便,它是基于实体和属性的,不用直接写关联表名:
// 查询ID为1的用户收藏的所有广告 String jpql = "SELECT a FROM User u JOIN u.favourites a WHERE u.id = :userId"; Query query = entityManager.createQuery(jpql); query.setParameter("userId", 1L); List<Advert> userFavourites = query.getResultList(); // 查询被超过5个用户收藏的广告 String countJpql = "SELECT a FROM Advert a WHERE SIZE(a.favouriters) > 5"; List<Advert> popularAdverts = entityManager.createQuery(countJpql).getResultList();
方法3:用原生SQL直接查询关联表
如果只需要关联表里的user_id和advert_id对应关系,不需要加载完整的实体对象,用原生SQL性能会更好:
// 查询所有收藏记录(仅获取用户ID和广告ID) String sql = "SELECT user_id, advert_id FROM faved_ads"; NativeQuery<Object[]> query = entityManager.createNativeQuery(sql); List<Object[]> favedRecords = query.getResultList(); // 遍历结果处理 for (Object[] record : favedRecords) { Long userId = (Long) record[0]; Long advertId = (Long) record[1]; // 这里可以做你需要的操作 } // 带条件的查询:获取收藏了ID为3的广告的所有用户ID String userSql = "SELECT user_id FROM faved_ads WHERE advert_id = :advertId"; NativeQuery<Long> userQuery = entityManager.createNativeQuery(userSql, Long.class); userQuery.setParameter("advertId", 3L); List<Long> favouriterIds = userQuery.getResultList();
方法4:使用类型安全的Criteria API
如果你偏好类型安全的查询方式(避免字符串拼写错误),可以用Criteria API:
// 查询ID为1的用户的所有收藏广告 CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Advert> cq = cb.createQuery(Advert.class); Root<User> userRoot = cq.from(User.class); Join<User, Advert> favouritesJoin = userRoot.join("favourites"); cq.select(favouritesJoin).where(cb.equal(userRoot.get("id"), 1L)); List<Advert> userFavourites = entityManager.createQuery(cq).getResultList();
补充说明
如果你的关联表faved_ads以后需要加额外字段(比如收藏时间),那就要把多对多拆成两个一对多,中间建一个FavedAd实体来映射关联表,但目前你的纯关联表场景,上面的方法都完全适用。
内容的提问来源于stack exchange,提问作者L-R
相关产品推荐
相关产品推荐

