入站通道介面卡

入站通道介面卡用於使用 JPA QL 對資料庫執行 select 查詢並返回結果。訊息載荷可以是單個實體,也可以是實體 List。以下 XML 配置了一個 inbound-channel-adapter

<int-jpa:inbound-channel-adapter channel="inboundChannelAdapterOne"  (1)
                    entity-manager="em"                              (2)
                    auto-startup="true"                              (3)
                    query="select s from Student s"                  (4)
                    expect-single-result="true"                      (5)
                    max-results=""                                   (6)
                    max-results-expression=""                        (7)
                    delete-after-poll="true"                         (8)
                    flush-after-delete="true">                       (9)
    <int:poller fixed-rate="2000" >
      <int:transactional propagation="REQUIRED" transaction-manager="transactionManager"/>
    </int:poller>
</int-jpa:inbound-channel-adapter>
1 在執行 query 屬性中的 JPA QL 後,inbound-channel-adapter 透過該通道傳送(帶有載荷的)訊息。
2 用於執行所需 JPA 操作的 EntityManager 例項。
3 表示元件是否應在應用程式上下文啟動時自動啟動的屬性。預設值為 true
4 其結果作為訊息載荷傳送的 JPA QL。
5 此屬性指示 JPQL 查詢結果是單個實體還是實體 List。如果值為 true,則將單個實體作為訊息載荷傳送。但是,如果在將其設定為 true 後返回多個結果,則會丟擲 MessagingException。預設值為 false
6 這個非零、非負的整數值告訴介面卡在執行 select 操作時,不要選擇超過給定行數的結果。預設情況下,如果未設定此屬性,則查詢會選擇所有可能的記錄。此屬性與 max-results-expression 互斥。可選。
7 一個用於計算結果集中最大結果數的表示式。與 max-results 互斥。可選。
8 如果要在執行查詢後刪除接收到的行,請將此值設定為 true。您必須確保元件作為事務的一部分執行。否則,您可能會遇到類似如下的異常:java.lang.IllegalArgumentException: Removing a detached instance …​
9 如果要在刪除接收到的實體後立即重新整理持久化上下文,並且不想依賴 EntityManagerflushMode,請將此值設定為 true。預設值為 false

配置引數參考

以下列表顯示了可以為一個 inbound-channel-adapter 設定的所有值:

<int-jpa:inbound-channel-adapter
  auto-startup="true"           (1)
  channel=""                    (2)
  delete-after-poll="false"     (3)
  delete-per-row="false"        (4)
  entity-class=""               (5)
  entity-manager=""             (6)
  entity-manager-factory=""     (7)
  expect-single-result="false"  (8)
  id=""
  jpa-operations=""             (9)
  jpa-query=""                  (10)
  named-query=""                (11)
  native-query=""               (12)
  parameter-source=""           (13)
  send-timeout="">              (14)
  <int:poller ref="myPoller"/>
 </int-jpa:inbound-channel-adapter>
1 這個生命週期屬性表示此元件是否應該在應用程式上下文啟動時自動啟動。此屬性預設為 true。可選。
2 介面卡在執行所需 JPA 操作後傳送帶有載荷訊息的通道。
3 一個布林標誌,指示在介面卡輪詢所選記錄後是否將其刪除。預設情況下,該值為 false(即不刪除記錄)。您必須確保元件作為事務的一部分執行。否則,您可能會遇到類似如下的異常:java.lang.IllegalArgumentException: Removing a detached instance …​。可選。
4 一個布林標誌,指示記錄是可以批次刪除還是必須逐條刪除。預設情況下,該值為 false(即可以批次刪除記錄)。可選。
5 要從資料庫中查詢的實體類的完全限定名。介面卡會根據實體類名自動構建 JPA 查詢。可選。
6 用於執行 JPA 操作的 jakarta.persistence.EntityManager 例項。可選。
7 一個 jakarta.persistence.EntityManagerFactory 例項,用於獲取執行 JPA 操作的 jakarta.persistence.EntityManager 例項。可選。
8 一個布林標誌,指示 select 操作預期返回單個結果還是結果 List。如果此標誌設定為 true,則將選擇的單個實體作為訊息載荷傳送。如果返回多個實體,則會丟擲異常。如果為 false,則將實體 List 作為訊息載荷傳送。預設值為 false。可選。
9 用於執行 JPA 操作的 org.springframework.integration.jpa.core.JpaOperations 實現。我們建議您不要提供自己的實現,而是使用預設的 org.springframework.integration.jpa.core.DefaultJpaOperations 實現。您可以使用 entity-managerentity-manager-factoryjpa-operations 屬性中的任何一個。可選。
10 此介面卡要執行的 JPA QL。可選。
11 此介面卡需要執行的命名查詢。可選。
12 此介面卡執行的原生查詢。您可以使用 jpa-querynamed-queryentity-classnative-query 屬性中的任何一個。可選。
13 一個 o.s.i.jpa.support.parametersource.ParameterSource 實現,用於解析查詢中引數的值。如果 entity-class 屬性有值,則忽略此項。可選。
14 傳送訊息到通道時最大等待時間(毫秒)。可選。

使用 Java Configuration 進行配置

以下 Spring Boot 應用程式展示瞭如何使用 Java 配置入站介面卡:

@SpringBootApplication
@EntityScan(basePackageClasses = StudentDomain.class)
public class JpaJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(JpaJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public JpaExecutor jpaExecutor() {
        JpaExecutor executor = new JpaExecutor(this.entityManagerFactory);
        jpaExecutor.setJpaQuery("from Student");
        return executor;
    }

    @Bean
    @InboundChannelAdapter(channel = "jpaInputChannel",
                     poller = @Poller(fixedDelay = "${poller.interval}"))
    public MessageSource<?> jpaInbound() {
        return new JpaPollingChannelAdapter(jpaExecutor());
    }

    @Bean
    @ServiceActivator(inputChannel = "jpaInputChannel")
    public MessageHandler handler() {
        return message -> System.out.println(message.getPayload());
    }

}

使用 Java DSL 進行配置

以下 Spring Boot 應用程式展示瞭如何使用 Java DSL 配置入站介面卡:

@SpringBootApplication
@EntityScan(basePackageClasses = StudentDomain.class)
public class JpaJavaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(JpaJavaApplication.class)
            .web(false)
            .run(args);
    }

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public IntegrationFlow pollingAdapterFlow() {
        return IntegrationFlow
            .from(Jpa.inboundAdapter(this.entityManagerFactory)
                        .entityClass(StudentDomain.class)
                        .maxResults(1)
                        .expectSingleResult(true),
                e -> e.poller(p -> p.trigger(new OnlyOnceTrigger())))
            .channel(c -> c.queue("pollingResults"))
            .get();
    }

}