入站通道适配器
一个 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>
inbound-channel-adapter
执行query
属性中的 JPA QL 后,放置消息(带有效负载)的通道。用于执行所需 JPA 操作的
EntityManager
实例。标记属性,指示组件是否应在应用程序上下文启动时自动启动。默认值为
true
。其结果作为消息的有效负载发送的 JPA QL。
此属性指示 JPQL 查询的结果是单个实体还是实体的
List
。如果值设置为true
,则单个实体将作为消息的有效负载发送。但是,如果在此设置为true
后返回多个结果,则会抛出MessagingException
。默认值为false
。此非零、非负整数值告诉适配器在执行选择操作时不要选择超过给定数量的行。默认情况下,如果没有设置此属性,则查询将选择所有可能的记录。此属性与
max-results-expression
互斥。可选。一个表达式,用于计算结果集中结果的最大数量。与
max-results
互斥。可选。如果您希望在执行查询后删除收到的行,请将此值设置为
true
。您必须确保该组件作为事务的一部分运行。否则,您可能会遇到类似以下异常:java.lang.IllegalArgumentException: Removing a detached instance …
如果您希望在删除接收到的实体后立即刷新持久化上下文,并且不想依赖
EntityManager
的flushMode
,请将此值设置为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>
此生命周期属性信号表示当应用程序上下文启动时,此组件是否应自动启动。该属性默认为
true
。可选。适配器向其发送带有执行所需 JPA 操作的有效负载的消息的通道。
一个布尔标志,指示在适配器轮询选定记录后是否删除这些记录。默认情况下,值为
false
(即不删除记录)。您必须确保组件作为事务的一部分运行。否则,您可能会遇到异常,例如:java.lang.IllegalArgumentException: Removing a detached instance …
。可选。一个布尔标志,指示记录是批量删除还是必须逐条删除。默认情况下,值为
false
(即可批量删除记录)。可选。要从数据库查询的实体类的完全限定名称。适配器根据实体类名称自动构建 JPA 查询。可选。
用于执行 JPA 操作的
jakarta.persistence.EntityManager
实例。可选。用于获取执行 JPA 操作的
jakarta.persistence.EntityManager
实例的jakarta.persistence.EntityManagerFactory
实例。可选。一个布尔标志,指示选择操作是返回单个结果还是
List
结果。如果此标志设置为true
,则选择的单个实体将作为消息的有效负载发送。如果返回多个实体,则会抛出异常。如果设置为false
,则实体的List
将作为消息的有效负载发送。默认值为false
。可选。org.springframework.integration.jpa.core.JpaOperations
的实现,用于执行 JPA 操作。我们建议不要提供自己的实现,而是使用默认的org.springframework.integration.jpa.core.DefaultJpaOperations
实现。您可以使用entity-manager
、entity-manager-factory
或jpa-operations
属性中的任何一个。可选。由本适配器执行的 JPA QL。可选。
需要由本适配器执行的命名查询。可选。
由本适配器执行的原生查询。您可以使用
jpa-query
、named-query
、entity-class
或native-query
属性中的任何一个。可选。o.s.i.jpa.support.parametersource.ParameterSource
的实现,用于解析查询中参数的值。如果entity-class
属性有值,则忽略。可选。在向通道发送消息时等待的最大时间(以毫秒为单位)。可选。
使用 Java 配置
以下 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();
}
}