Select 来自 JPA 存储库的另一个 table 的数据

Select data from another table from JPA repository

我在 JPA 存储库中有这个查询:

@Repository
public interface PaymentTransactionsDailyFactsRepository extends JpaRepository<PaymentTransactionsDailyFacts, Integer> {

    @Query(value = "SELECT " + 
            " COUNT(*) count, " + 
            " SUM(amount) volume, " + 
            " DATE(created_at) date, " + 
            " YEAR(created_at) year, " + 
            " MONTH(created_at) month, " + 
            " WEEK(created_at) week, " + 
            " DAY(created_at) day, " + 
            " type transaction_type, " + 
            " contract_id, merchant_id, terminal_id, " + 
            " status, card_brand, currency " + 
            " FROM payment_transactions " + 
            " WHERE status NOT IN ('pending_async','pending','pending_review','in_progress','new') AND created_at BETWEEN :start_date AND :end_date " + 
            " GROUP by date, contract_id, merchant_id, terminal_id, transaction_type, status, card_brand, currency", nativeQuery = true)
    List<PaymentTransactionsDailyFacts> generateDailyFacts(@Param("start_date") LocalDate start_date, @Param("end_date") LocalDate end_date);
}

但是当我在 Spring Scheduler 中执行它时出现错误:

SQL Error: 1054, SQLState: 42S22
Caused by: java.sql.SQLSyntaxErrorException: No such column: id

当我在 MariaDB 中执行这个查询时,它工作正常:

SELECT  COUNT(*) count,  SUM(amount) volume,  DATE(created_at) date,  YEAR(created_at) year,  MONTH(created_at) month,  WEEK(created_at) week,  DAY(created_at) day,  type transaction_type,  contract_id, merchant_id, terminal_id,  status, card_brand, currency  FROM payment_transactions  WHERE status NOT IN ('pending_async','pending','pending_review','in_progress','new') AND created_at BETWEEN '2011-04-11 00:00:01' AND '2029-04-11 00:00:00'  GROUP by date, contract_id, merchant_id, terminal_id, transaction_type, status, card_brand, currency

如您所见,我是 运行 table payment_transactions 的本机查询,但我期待 table payment_transactions_daily_facts 的结果。有没有办法正确实现这个查询?

尝试在查询

中添加 id
@Query(value = "SELECT " + 
            " id," + 
            " COUNT(*) count, " + 
            " SUM(amount) volume, " + 
            " DATE(created_at) date, " + 
            " YEAR(created_at) year, " + 
            " MONTH(created_at) month, " + 
            " WEEK(created_at) week, " + 
            " DAY(created_at) day, " + 
            " type transaction_type, " + 
            " contract_id, merchant_id, terminal_id, " + 
            " status, card_brand, currency " + 
            " FROM payment_transactions " + 
            " WHERE status NOT IN ('pending_async','pending','pending_review','in_progress','new') AND created_at BETWEEN :start_date AND :end_date " + 
            " GROUP by date, contract_id, merchant_id, terminal_id, transaction_type, status, card_brand, currency", nativeQuery = true)
    List<PaymentTransactionsDailyFacts> generateDailyFacts(@Param("start_date") LocalDate start_date, @Param("end_date") LocalDate end_date);

如果你想获得给定 start_dateend_date 之间的所有 PaymentTransactionsDailyFacts 个实体,并且它们的 status 不是 ('pending_async', 'pending','pending_review','in_progress','new'),可以使用如下查询。

@Query(value = "SELECT * " 
            " FROM payment_transactions " + 
            " WHERE status NOT IN ('pending_async','pending','pending_review','in_progress','new') AND created_at BETWEEN :start_date AND :end_date " + 
            " GROUP by date, contract_id, merchant_id, terminal_id, transaction_type, status, card_brand, currency", nativeQuery = true)

但是,由于您在查询中使用了 group by,您似乎正在尝试获取一些聚合数据,而不仅仅是满足条件的 PaymentTransactionsDailyFacts 实体的列表。 如果是这样,那你就大错特错了。你必须使用 projections.

这是有关如何使用 spring 数据投影的快速教程。 https://www.baeldung.com/spring-data-jpa-projections

或。你可以在这里阅读官方文档。 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

更新:使用投影

  1. 首先在项目某处创建如下界面。您应该根据需要调整 return 类型。

    public interface PtdsDTO {
        Integer getCount();
        BigDecimal getVolume();
        LocalDate getDate();
        Short getYear();
        Short getMonth();
        Short getWeek();
        Short getDay();
        String getTransactionType();
        Integer getContactId();
        Integer getMerchantId();
        Integer getTerminalId();
        String getStatus();
        String getCardBrand();
        String getCurrency();
    }
    
  2. 然后,在相应存储库的顶部导入该接口。

  3. 将存储库的 return 类型更改为 List<PtdsDTO>

    List<PtdsDTO> generateDailyFacts(@Param("start_date") LocalDate start_date, @Param("end_date") LocalDate end_date);
    

就是这样。