天天看點

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

繼續閱讀