公司有一个springboot项目,用户存在user表中,用户的角色存在role表中。现需要返回所有用户列表,并且返回该用户的角色,但同一个用户有可能有多个角色,需要将角色拼接起来返回。
原始数据如下:
user表
id | name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
role表
userid | name |
---|---|
1 | 部门经理 |
1 | 项目经理 |
2 | 架构师 |
2 | 开发 |
我们需要返回的结果是
姓名 | 角色 |
---|---|
张三 | 部门经理,项目经理 |
李四 | 架构师 |
王五 | 开发 |
在MySql 中可以使用GROUP_CONCAT函数配合GROUP BY来实现
select user.*,GROUP_CONCAT(role.name) from user left join role on role.userid = user.id group by user.id orber by user.id
但是JPA原生HQL并不能直接支持GROUP_CONCAT,以上sql如果在JPA中去使用就需要用nativeQuery来实现。由于其它的接口都是用的HQL写的,这个换成nativeQuery不友好。网上找了些资料,其中stackoverflow提到可以增加一个类,并在application.properties配置文件中指定这个类,之后就可在在HQL中直接使用了。
public class SqlFunctionsMetadataBuilderContributor implements MetadataBuilderContributor{
@Override
public void contribute(MetadataBuilder metadataBuilder) {
metadataBuilder.applySqlFunction(
"group_concat",
new StandardSQLFunction(
"group_concat",
StandardBasicTypes.STRING
)
);
}
}
spring.jpa.properties.hibernate.metadata_builder_contributor=你刚才新的类的完整路径,需要包含包名,例如com.sql.SqlFunctionsMetadataBuilderContributor
JPA示例
@Query("select new UserWithRole(tu,group_concat(tr.name)) from User tu left join Role tr on tr.userid = tu.id group by tu.id order by tu.id")
List<UserWithRole> retrieveAllUser();