在JPA存储库方法中使用本机sql查询获取实体关系

问题描述 投票:0回答:1

我有一个存储库方法来获取电子邮件订阅

    @Query("SELECT es FROM com.cargurus.emailsubscriptions.entity.EmailSubscription es "
        + "JOIN FETCH es.subscriber s "
        + "WHERE es.id > :batchStartId "
        + "AND es.subscriptionTypeId = :typeId "
        + "AND es.active = :active "
        + "ORDER BY es.id ASC")
    List<EmailSubscription> findByIdGreaterThanAndSubscriptionTypeIdAndActive(
        @Param("batchStartId") long batchStartId,
        @Param("typeId") Integer typeId,
        @Param("active") Boolean active,
        Pageable pageable);

以下是 EmailSubscriptions 的定义方式。

public class EmailSubscription {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(updatable = false, nullable = false)
    private Long id;

    @Column(name = "type_id")
    private Integer subscriptionTypeId;
    private Boolean active;
    @Pattern(regexp = LOCALE_VALIDATION_REGEX, message = "invalid code")
    private String locale;
    private LocalDateTime lastSentTimestamp;
    private Integer lastSentSequence;
    private Long lastUpdatePersonId;
    private LocalDateTime lastUpdateTimestamp;
    private LocalDateTime creationTimestamp;

    @ManyToOne(targetEntity = Subscriber.class, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "subscriber_id", referencedColumnName = "id")
    private Subscriber subscriber;
}

不幸的是,对于一批 10k 条记录(10 秒以上)来说,这个查询非常昂贵。 所以我编写了一个原生 SQL 查询,不到 1 秒即可获取 10k 记录。

            @Query(value = "SELECT es.* FROM subscriptions.email_subscriptions es "
                + "IGNORE INDEX (PRIMARY) "
                + "JOIN subscriptions.subscribers s ON es.subscriber_id = s.id "
                + "WHERE es.type_id = :typeId "
                + "AND es.active = :active "
                + "AND es.id > :batchStartId "
                + "ORDER BY es.id ", nativeQuery = true)

但不幸的是,此查询仅获取 EmailSubscriptions,而没有其订阅者关系。如何使用本机 sql 查询在 EmailSusbcription 中获取订阅者

java spring-boot jpa spring-data-jpa
1个回答
0
投票

试试这个。

@Query(value = "SELECT es.id as es_id, es.type_id as es_type_id, es.active as es_active, es.locale as es_locale, " +
               "es.last_sent_timestamp as es_last_sent_timestamp, es.last_sent_sequence as es_last_sent_sequence, " +
               "es.last_update_person_id as es_last_update_person_id, es.last_update_timestamp as es_last_update_timestamp, " +
               "es.creation_timestamp as es_creation_timestamp, " +
               "s.id as s_id, s.name as s_name, s.email as s_email " + // select subscriber fields
               "FROM subscriptions.email_subscriptions es " +
               "JOIN subscriptions.subscribers s ON es.subscriber_id = s.id " +
               "WHERE es.type_id = :typeId " +
               "AND es.active = :active " +
               "AND es.id > :batchStartId " +
               "ORDER BY es.id ",
       nativeQuery = true)
List<Object[]> findByIdGreaterThanAndSubscriptionTypeIdAndActiveWithSubscriber(
    @Param("batchStartId") long batchStartId,
    @Param("typeId") Integer typeId,
    @Param("active") Boolean active);

由于您在

List<Object[]>
中获取本机查询结果,因此您可以手动将结果映射到您的实体。

© www.soinside.com 2019 - 2024. All rights reserved.