Inbound Channel Adapter

Inbound Channel Adapter 用於使用 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 inbound-channel-adapterquery 屬性中執行 JPA QL 後,將訊息(連同酬載)放入的通道。
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 用於取得執行 JPA 操作的 jakarta.persistence.EntityManager 實例的 jakarta.persistence.EntityManagerFactory 實例。選填。
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 組態進行設定

以下 Spring Boot 應用程式顯示如何使用 Java 設定 inbound adapter 的範例

@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 設定 inbound adapter 的範例

@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();
    }

}