设计:Spring集成jdbc最佳实践

时间:2014-06-27 09:24:07

标签: spring-integration

在项目中使用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>

如果对概念有所了解,请纠正我。

1 个答案:

答案 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"/>