【问题标题】:Get fields of spring jpa interface projection获取spring jpa界面投影的字段
【发布时间】:2021-11-22 20:02:39
【问题描述】:

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

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

调用方法 public abstract java.lang.Long ConfirmationDTO.memberID() 不是访问器方法!

这是我的投影界面

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

和 DAO

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

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

【问题讨论】:

  • 请在您的问题中添加更多详细信息
  • 请不要使用Optional 进行收藏?当没有什么要查询时,它总是会返回一个空集合,所以Optional 是矫枉过正。
  • 感谢@M.Deinum ,将应用它

标签: spring jpa spring-data-jpa


【解决方案1】:

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

how-to-map-sql-native-query-result-into-dto-in-spring-jpa-repository

这是来自该线程的示例代码:

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

【讨论】:

    【解决方案2】:

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

      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() 才能分配这些值。

    【讨论】:

    • 具体类“Confirmation”有什么作用?
    • @Fancy,即模型或实体类。
    【解决方案3】:

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

    最简单的方法是将你的界面变成一个类。

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-06-01
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 2021-10-29
      • 2019-01-07
      相关资源
      最近更新 更多