获取spring个jpa接口投影的字段

Get fields of spring jpa interface projection

我在 spring jpa 存储库中调用了这个存储过程,并且我正在使用基于接口的投影。

每当我尝试调用接口投影方法时,我都会收到此错误

Invoked method public abstract java.lang.Long ConfirmationDTO.memberID() is no accessor method!

这是我的投影界面

public interface ConfirmationDTO {
       Long memberID();
       LocalDate dateEntry();
}

和 DAO

@Query(value=" CALL get_confirmation(:startDate) ", nativeQuery=true)
List<ConfirmationDTO> getConfirmation(LocalDate startDate);

是否可以从界面投影中获取字段值?

您可以创建一个实现组件,它会自动装配,但不建议注释 DTO classes。

最简单的方法是将您的界面变成 class。

归根结底,它只是一个 DTO,没有逻辑,在测试中您可以随意模拟它,只需填充属性即可。

我不认为你的 DTO 是一个接口有什么意义,除非 Class 某个地方正在实现多个接口,而这个接口就是其中之一。

如果是这种情况,我会重新考虑实施 - 例如实现 TheOtherInterface 扩展 Person.

我发现了另一个使用 Tuple 的 SO 线程,这帮助我实现了上述问题的目标。

这是该线程的示例代码:

    @Repository
    public interface StockRepository extends RevisionRepository<Stock, Long, Integer>, JpaRepository<Stock, Long> {
    
   @Query(value = "SELECT stock_akhir.product_id AS productId, stock_akhir.product_code AS productCode, SUM(stock_akhir.qty) as stockAkhir "
    + "FROM book_stock stock_akhir "
    + "where warehouse_code = (:warehouseCode) "
    + "AND product_code IN (:productCodes) "
    + "GROUP BY product_id, product_code, warehouse_id, warehouse_code", nativeQuery = true)
List findStockAkhirPerProductIn(@Param("warehouseCode") String warehouseCode, @Param("productCodes") Set productCode); }

他们在服务中映射元组:

public List<StockTotalResponseDto> findStocktotal() {
List<Tuple> stockTotalTuples = stockRepository.findStocktotal();

List<StockTotalResponseDto> stockTotalDto = stockTotalTuples.stream()
        .map(t -> new StockTotalResponseDto(
                t.get(0, String.class), 
                t.get(1, String.class), 
                t.get(2, BigInteger.class)
                ))
        .collect(Collectors.toList());

return stockTotalDto;
}

让我来解释一下如何轻松做到这一点。

  public class Confirmation {
        private Long memberId;
        private LocalDate dateEntry;
        //add other fields
        //provide getters and setters

    }
    //tuple
    public inteface ConfirmationTuple {
        Long getMemberId ();
        LocalDate getDateEntry ();

    }
        //Your repository
    @Query(value = " CALL get_confirmation(:startDate) ", nativeQuery = true)
    List<ConfirmationTuple> getConfirmation (LocalDate startDate);

Spring 会为您完成剩下的工作。要从第一个元组中获取 memberId,您要做的就是

yourDAO.getConfirmation(startDate).get(0).getMemberId();

这里的问题是元组中的 get 方法必须与存储库中的查询返回的字段名称相对应。例如,如果您的查询返回以下列 [memberName,myDate],您的 Tuple 接口必须具有 getMemberName 和 getMyDate() 才能分配这些值。