JPA: 投影(Projection)的用法
程序员文章站
2022-04-01 15:50:46
...
有一个不方便的地方,@Query注解,如果查询直接是Select c from User c
,这时候,查询的返回对象就是User这个完整的对象,包含所有字段,对于比较庞大的domain类,这个查询时就比较要命,并不是所有的字段都能用到,比较头疼。另外,如果定义select c.firstName as firstName,c.lastName as lastName from Customer c
这个查询结果,返回的对象是Object类型,而且无法直接转换成Customer对象,这样用起来就不是很方便。
不想mybatis,可以定义一个UserDTO,
对于这种情况,JPA提供了一种声明方式来解决,即声明一个接口类,然后直接使用这个接口类接受返回的数据即可。
1、增加UserProjection接口类
package com.cxy.favourite.dto.projection;
import org.springframework.beans.factory.annotation.Value;
/**
* 仅查询User的userName和email,还有借助@Value注解做聚合展示 得到Information().
* 可以使用get
*/
public interface UserProjection {
@Value("#{target.userName + ' ' + target.email}")
String getInformation();
String getUserName();
String getEmail();
}
2.Repository增加方法
//TODO PROJECTION投影 @Query("select u.userName as userName ,u.email as email from User u") Collection<UserProjection> findAllNameAndEmail();
3.测试(大概这么个意思,具体在修改)
/**
* 查询用户(分页)
* //TODO wrong way
* @return
*/
@RequestMapping(value = "/projections", method = RequestMethod.GET)
@LogManage(description = "测试投影使用")
public Map<String,Object> projection() throws Exception{
Map<String,Object> map = new HashMap<>();
Collection<UserProjection> projections = userRepository.findAllNameAndEmail();
System.out.println(projections);
System.out.println(projections.size());
for(UserProjection u:projections){
map.put("userName:",u.getUserName());
map.put("email:",u.getEmail());
map.put("information:",u.getInformation());
}
return map;
}