我正在处理一个有50k条目的PostgreSQL表USERS。一个USER可以有一个或多个GROUP。这两个表使用连接表USER_GROUP(带有user_id和group_id)连接。关系定义为:
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name="user_group",
joinColumns={
@JoinColumn(name="user_uid", referencedColumnName="user_uid")},
inverseJoinColumns={
@JoinColumn(name="group_id", referencedColumnName="group_id")})
private Set<GroupEntity> groups = new HashSet<>();
在真实的的数据库中,很少有用户有一个指定的组。在一个用例中,我需要查询所有用户和他们各自的组。组名需要存储在一个字符串中。我使用以下命令加载组:
String groups = userList.add(String.join(",", user.getGroups().stream().map(Group::getName) .collect(Collectors.toList())));
这个查询非常慢,因为Hibernate会为每个用户创建一个选择查询。有什么方法可以加快速度吗?我错过了什么吗?
我的替代方法是创建一个数据库视图:
CREATE VIEW user_view AS SELECT user.user_id, group_names from user left outer join (select user_id, string_agg(group_name, ',') group_names from user_group natural left join group GROUP BY user_id) AS g ON user.user_id = g.user_id;
有没有一种方法可以有效地使用Hibernate来完成这个任务?我使用的是Quarkus和Panache,但是也有一些Criteria代码。
我希望我的例子容易理解:)
1条答案
按热度按时间0yg35tkg1#
是的,实际上非常简单。你可以在你的HQL查询中使用连接获取:
通过这种方式,Hibernate将沿着所有集合元素作为单个查询的一部分进行连接和获取。其他可能的替代方法是使用实体图,或专门的HQL查询,例如。
最后一个查询将选择用户id和逗号分隔的列表作为字符串。