欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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;
    }