我有一个存储库方法来获取电子邮件订阅
@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 中获取订阅者
试试这个。
@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[]>
中获取本机查询结果,因此您可以手动将结果映射到您的实体。