当只使用数据库实体类接收数据查询结果不满足业务需求时,需要自定义类来接收查询结果;以下为两种实现方式:
第一种方式 使用构造函数来接收查询结果
根据业务需求创建实体类
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class UserAndRoleBean {
private Long userId;
private String username;
private Long roleId;
private String roleName;
}
在Repository中声明方法时,@Query中使用new UserAndRoleBean(...)方式接收数据库语句查询的返回值;在这里要注意,查询语句的查询结果数据类型要和构造函数的入参数据类型一一对应
@Query(value = "select new com.micro.user.bean.UserAndRoleBean(u.id,u.username,r.id,r.name) " +
"from User u join Role r on u.roleId = r.id where u.id = ?1")
UserAndRoleBean getUserAndRoleByUserId(Long userId);
第二种方式 使用JPA提供的Objection
创建Objection接口;在接口中,以get+首字母大写的字段名为方法名命名(例如:查询语句的查询结果字段名为name,接口中的方法名为getName)
public interface UserAndRoleProjection {
Long getUserId();
String getUsername();
Long getRoleId();
String getRoleName();
}
在Repository中声明方法,@Query的查询结果要与Objection中的方法名去掉get之后首字母小写相同;并且查询语句中的u.name和getName相同也无法映射,要在查询语句中使用u.name as name才能映射
@Query("select u.id as userId,u.username as username," +
"r.id as roleId,r.name as roleName " +
"from User u join Role r" +
" on u.roleId = r.id where u.id = ?1")
UserAndRoleBean getUserAndRoleByUserId(Long userId);
当使用QueryDSL查询时也可以使用Objection
public UserAndRoleBean getUserAndRoleByUserId(Long userId){
QUser user = QUser.user;
QRole role = QRole.role;
return queryFactory()
.select(Projections.bean(UserAndRoleBean.class,user.id.as("userId"),
user.username,role.id.as("roleId"), role.name.as("roleName")))
.from(user)
.join(role)
.on(user.roleId.eq(role.id))
.where(user.id.eq(userId))
.fetchFirst();
}
当查询结果为集合时也可以使用stream
public List<UserAndRoleBean> getUserAndRoleByUserId(Long userId){
QUser user = QUser.user;
QRole role = QRole.role;
return queryFactory().select(user.id,user.username,role.id,role.name)
.from(user)
.join(role)
.on(user.roleId.eq(role.id))
.where(user.id.ne(userId))
.fetch()
.stream()
.map(tuple -> {
UserAndRoleBean bean = new UserAndRoleBean();
bean.setRoleId(bean.getRoleId());
bean.setUserId(bean.getUserId());
bean.setRoleName(bean.getRoleName());
bean.setUsername(bean.getUsername());
return bean;
}).collect(Collectors.toList());
}