入站通道适配器
入站通道适配器用于使用 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 | 如果要在删除接收到的实体后立即刷新持久化上下文,并且不想依赖于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>
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-manager 、entity-manager-factory 或jpa-operations 属性。可选的。 |
10 | 此适配器要执行的 JPA QL。可选的。 |
11 | 此适配器需要执行的命名查询。可选的。 |
12 | 此适配器执行的原生查询。您可以使用任何jpa-query 、named-query 、entity-class 或native-query 属性。可选的。 |
13 | 用于解析查询中参数值的o.s.i.jpa.support.parametersource.ParameterSource 的实现。如果entity-class 属性具有值,则忽略。可选的。 |
14 | 将消息发送到通道时要等待的最长时间(以毫秒为单位)。可选的。 |
使用 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();
}
}