有一个不方便的地方,@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;}