2017-01-31 28 views
3

在這種情況下有一種簡單的方法可以使用@Projection春季引導最簡單的方式來表達投影

報告實體有大的領域(例如,一個內容場完整的HTML文本),我不需要在端點提供。

@Repository 
public interface IReportRepository extends BaseRepository<Report, Long> { 

    List<Report> findAll(); // working fine... BUT with fields that not need 

    @Query(nativeQuery = true, value= "SELECT id, acronym FROM report") 
    List<Object[]> findSomeFields1(); // BAD JSON, no field name! 

    @Query(nativeQuery = true, value= "SELECT id, acronym FROM report") 
    List<Map> findSomeFields2(); // ERROR! Failed to convert 
     // there are something as JSON Row Mapper? 

} 

(他們ReportController在端點處將其作爲JSON,只有它)

取而代之的是@Query我需要使用@Projection(...) ...如何使用它(簡單辦法!)?

+0

是它也對你合適,你用'的findAll()'方法,只是不報告的某些字段導出到用戶帶來什麼影響? – Patrick

+0

Hi @Patrick Hi @Patrick是從特定的(本地)查詢中查找All(),只返回具有結構化數據的期望字段,如實體findAll()中那樣。 –

+0

您是否需要使用'@ Projection'或者在沒有使用其他解決方案的情況下使用它? – Patrick

回答

4

在春節項目庫中,如果你想擁有你所獲得的數據進行更多的控制,你可以檢查這個項目https://github.com/spring-projects/spring-data-examples/tree/master/rest/projections

反正,你可以使用QueryDSLSpringlets庫從你的Spring數據返回預測爲例庫。

下面是有關如何使用QueryDSLSpringlets在一起的例子:

創建一個只包含要獲得具體領域的一個新的類。例如,對於Owner實體,您可以創建僅包含idfirstNamelastName字段的OwnerInfo投影。

public class OwnerInfo { 

    private Long id; 

    @Size(min = 3, max = 30) 
    private String firstName; 

    @NotNull 
    @Size(min = 3, max = 30) 
    private String lastName; 

} 

Owner例如,創建一個名爲OwnerRepositoryCustom並定義將返回投影取景器一個新的倉庫接口。

public interface OwnerRepositoryCustom { 

    public Page<OwnerInfo> findByFirstNameLike(String firstName, Pageable pageable); 

} 

創建我們的OwnerRepositoryCustom的實現。該課程應該從Springlets項目延伸QueryDslRepositorySupportExt

public class OwnerRepositoryImpl extends QueryDslRepositorySupportExt<Owner> implements OwnerRepositoryCustom { 

    OwnerRepositoryImpl() { 
     super(Owner.class); 
    } 

    public Page<OwnerInfo> findByFirstNameLike(String firstName, Pageable pageable) { 

     QOwner owner = QOwner.owner; 

     JPQLQuery<Owner> query = from(owner); 

     if (StringUtils.isNotEmpty(firstName)) { 
      BooleanBuilder searchCondition = new BooleanBuilder();       

      searchCondition.and(owner.firstName.eq(firstName)); 

      if (searchCondition.hasValue()) { 
      query.where(searchCondition); 
      } 
     } 

     Path<?>[] paths = new Path<?>[] {owner.id,owner.firstName,owner.lastName};   

     AttributeMappingBuilder mapping = buildMapper() 
      .map(ID, owner.id) 
      .map(FIRST_NAME, owner.firstName) 
      .map(LAST_NAME, owner.lastName); 

     return loadPage(query, pageable, Projections.constructor(OwnerInfo.class, owner.id, owner.firstName, owner.lastName)); 
    } 

} 

現在,從JpaRepository<Owner, Long> and OwnerRepositoryCustom`接口擴展OwnerRepository接口。

public interface OwnerRepository extends OwnerRepositoryCustom, JpaRepository<Owner, Long> { 

} 

通過這些簡單的步驟,您將能夠返回存儲庫方法中的投影。

希望它能幫助,

+0

謝謝!好的選擇和解釋。關於'@ Query'和'@ Projection'的簡單性,沒有直接的解決方案?想象一下'SELECT id,首字母縮略詞FROM report',其中包含'(id,acronym)'的一些投影規範...... –

+0

從Spring博客的例子看來,如果您創建一個用@Projection(name =「report」,types = Report.class)註釋的'ReportInfo'投影,並將該投影定義爲您的操作的返回類型' @Query(nativeQuery = true,value =「SELECT id,首字母縮寫詞FROM report」) List findSomeFields1(); // BAD JSON,沒有字段名稱!'Spring Data應該返回一個有效的投影對象。希望能幫助到你! – jcgarcia

+0

我在假期,但會測試,非常感謝......它似乎是答案的核心(!),您能否將@ Projection代碼行顯示爲我的* IReportRepository *類的片段? (沒有*實體*聲明需要?) –