天天看点

JPA: 投影(Projection)的用法

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

继续阅读