从JPA存储库中的另一个表中选择数据

时间:2019-07-07 22:44:58

标签: spring spring-boot spring-data-jpa mariadb jpa-2.0

我在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

如您所见,我正在为表payment_transactions运行此本机查询,但是我期望表payment_transactions_daily_facts的结果。有没有办法正确实施此查询?

2 个答案:

答案 0 :(得分:1)

尝试在查询中添加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);

答案 1 :(得分:1)

如果您要获取给定PaymentTransactionsDailyFactsstart_date之间的所有end_date实体,而它们的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实体的列表。 如果真是这样,那么您做错了所有。您必须使用投影

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

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

更新:使用投影

  1. 首先在项目中某处的下面创建一个界面。您应该根据需要调整退货类型。

    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. 将存储库的返回类型更改为List<PtdsDTO>

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

就这样。