JPQL 和 JPA 中的本机查询“GROUP_CONCAT”是否有替代方案?

Sab*_*kya 5 java mysql jpa jpql spring-boot

我正在尝试使用 jpql 和 JPA 来获取配置文件的配置文件菜单。我的“个人资料”和“个人资料菜单”实体具有多对一的关系。

我尝试过研究这些答案,但找不到任何可行的解决方案。

如何在Spring Boot应用程序中添加非标准化sql函数?

使用 JPA 和 Hibernate 注册 SQL 函数

https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/

我也浏览了这个链接,似乎和我有同样的问题, How to register non-standardized SQL function Manual in Spring Boot application?

使用本机查询时,我可以使用以下查询获取数据:

 SELECT
 GROUP_CONCAT(pm.user_menu_id SEPARATOR ',')
 AS profile_menu_ids,
 p.description
 FROM profile p
 LEFT JOIN profile_menu pm ON p.id = pm.profile_id
 WHERE
 p.id =:profileId
 AND
 pm.status = 'Y'
 GROUP BY p.id
Run Code Online (Sandbox Code Playgroud)

上述查询为我提供的数据为,

个人资料菜单 ID 描述
4,5 管理员简介

jpql 和 JPA 中是否有任何方法或替代方案来获得上述结果?

Kon*_*ger 0

您可以考虑使用FluentJPA,它支持任何自定义函数:

public ProfileMenuGroup getMenuIdsByProfile(int profileId) {
    FluentQuery query = FluentJPA.SQL((Profile p,
                                       ProfileMenu pm) -> {
        String menuIds = alias(GROUP_CONCAT(pm.getUserMenuId(), ","),
                                            ProfileMenuGroup::getProfileMenuIds);
        String description = alias(p.getDescription(), ProfileMenuGroup::getDescription);

        SELECT(menuIds, description);
        FROM(p).LEFT_JOIN(pm).ON(p == pm.getProfile());
        WHERE(p.getId() == profileId && pm.getStatus() == "Y");
        GROUP(BY(p.getId()));
    });
    return query.createQuery(em, ProfileMenuGroup.class).getSingleResult();
}
Run Code Online (Sandbox Code Playgroud)

查询生成以下 SQL(profileId自动绑定):

SELECT GROUP_CONCAT(t1.user_menu_id SEPARATOR ',') AS profile_menu_ids,
                                    t0.description AS description 
FROM profile t0  LEFT JOIN profile_menu t1  ON (t0.id = t1.profile_id) 
WHERE ((t0.id = ?1) AND (t1.status = 'Y')) 
GROUP BY  t0.id
Run Code Online (Sandbox Code Playgroud)

给出以下类型声明:

SELECT GROUP_CONCAT(t1.user_menu_id SEPARATOR ',') AS profile_menu_ids,
                                    t0.description AS description 
FROM profile t0  LEFT JOIN profile_menu t1  ON (t0.id = t1.profile_id) 
WHERE ((t0.id = ?1) AND (t1.status = 'Y')) 
GROUP BY  t0.id
Run Code Online (Sandbox Code Playgroud)