在项目中使用Spring Integration之后,我的观察是仅在流的开头或结尾使用jdbc适配器或网关。如果我们在流动的中间使用它们,那么它将变得过于冗长和复杂。
例如:
<jdbc:outbound-gateway
query="select * from foo where
c1=:headers[c1] AND
c2=:headers[c2] AND
c3=:headers[c3] AND
c4=:headers[c4]"
row-mapper="fooMapper" data-source="myDataSource" max-rows-per-poll="100000" />
<int:service-activator ref="serviceActivator" method="processFoo" />
在上面的<jdbc:outbound-gateway>
中,我们需要在Message的标题中传递所有占位符(c1,c2,c3,c4)。我们需要在java代码和xml文件中来回查看where条件或where子句太多的任何更改。
它也容易出错。例如,如果我们将:headers[c1]
拼错至:headers[d1]
,则不会抛出任何异常并将:headers[d1]
替换为null
。
如果查询没有返回任何行,那么它将默认抛出异常。因此,我们必须使用requires-reply="false"
来更改默认行为。
如果我们想在查询没有返回任何值时继续,那么我们必须向网关添加建议,如下所示:
<jdbc:outbound-gateway ... >
<jdbc:request-handler-advice-chain>
<bean class="com.service.NullReplyAdvice" />
</jdbc:request-handler-advice-chain>
</jdbc:outbound-gateway>
如果对概念有所了解,请纠正我。
答案 0 :(得分:0)
我们需要在java代码和xml文件中来回查看where条件或where子句太多的任何更改。
即使是围绕JDBC的原始Java代码也是如此:如果你改变模型,你当然应该更改SELECT
,因为它只是一个字符串。这就是为什么要做出类型安全的大量工作 - ORM,QueryDSL,Spring-Data等。
如果我们拼写错误:headers [c1] to:headers [d1]那么它不会抛出任何异常并用null替换:headers [d1]。
那是因为headers
只是Map
,如果地图中没有null
,那么你得到key
就是事实。要解决这个拼写错误问题,您可以将POJO payload
与getter或一些自定义标题一起使用 - 再次使用带有getter的POJO。在这种情况下,您最终会遇到异常,即没有针对对象的此类属性。虽然您只会在运行时看到该问题,但不会在编译时看到。同样是Hashtable
- 仅在运行时。
因此,我们必须使用requires-reply =“false”来更改默认行为。
您应该在设计时理解它:允许或不为组件返回任何内容。
最后一个想法很好。你不介意分享你的NullReplyAdvice
吗?
实际上我在JDBC网关之前使用<filter>
实现了相同的目的:确定是否有count(*)
查询提取的内容。当SELECT
返回行时,我可以从那里开始流向不同的逻辑,而不是直接流。
<强>更新强>
如果要使用Model对象在Message中保留特定于业务的值,只需将此对象放到标题中即可:
public class Foo {
private String foo1;
private String foo2;
public String getFoo1() {
return foo1;
}
public String getFoo2() {
return foo2;
}
}
...
MessageBuilder.withPayload(payload).setHeader("foo", foo).build();
...
<jdbc:outbound-gateway
query="select * from foo where
c1=:headers[foo].foo1 AND
c1=:headers[foo].foo2"/>