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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:33:02