设计:Spring 集成 jdbc 最佳实践 [英] Design: Spring Integration jdbc best practice

查看:24
本文介绍了设计:Spring 集成 jdbc 最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个项目中使用 Spring Integration 后,我的观察是只在流程的开始或结束时使用 jdbc 适配器或网关.如果我们在流程中使用它们,那么它会变得过于冗长和复杂.

After using Spring Integration in a project, my observation is to use jdbc adapter or gateway only at the start or end of the flow. If we use them in the middle of flow then it will become too verbose and complex.

例如:

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

在上面的中,我们需要把所有的占位符(c1、c2、c3、c4)都传入Message的头部.我们需要在java代码和xml文件中来回查看where条件或where子句过多时的任何变化.

In the above <jdbc:outbound-gateway>, we need to pass all the placeholders (c1, c2, c3, c4) in the header of Message. We need to look back and forth in java code and xml file for any change in where condition or when there are too many where clauses.

它也容易出错.例如,如果我们将 :headers[c1] 拼错为 :headers[d1] 那么它不会抛出任何异常并替换 :headers[d1]code> 与 null.

It is also error prone. For example, if we misspelled :headers[c1] to :headers[d1] then it will not throw any exception and replace :headers[d1] with null.

如果查询没有返回任何行,那么它默认会抛出异常.因此,我们必须使用 requires-reply="false" 来更改默认行为.

If query does not return any row then it will throw exception by default. So, we have to use requires-reply="false" to change default behaviour.

如果我们想在查询没有返回任何值时继续,那么我们必须向网关添加通知,如下所示:

If we want to proceed when query does not return any value then we have to add advice to gateway, as shown below:

<jdbc:outbound-gateway ... >
    <jdbc:request-handler-advice-chain>
        <bean class="com.service.NullReplyAdvice" />
    </jdbc:request-handler-advice-chain>
</jdbc:outbound-gateway>

如果对概念的理解有缺陷,请纠正我.

Please correct me if there are flaws in understanding of the concept.

推荐答案

我们需要在java代码和xml文件中来回查看where条件的任何变化或where子句过多时.

We need to look back and forth in java code and xml file for any change in where condition or when there are too many where clauses.

即使对于围绕 JDBC 的原始 Java 代码也是如此:如果您更改模型,您当然应该更改 SELECT,因为它只是一个字符串.这就是为什么要进行大量工作以使其类型安全 - ORM、QueryDSL、Spring-Data 等.

It's true even for raw Java code around the JDBC: if you change the model you, of course, should change the SELECT, because it is just a String. And that's why there is a lot of work to make it type-safe - ORM, QueryDSL, Spring-Data etc.

如果我们将 :headers[c1] 拼错为 :headers[d1] 那么它不会抛出任何异常并将 :headers[d1] 替换为 null.

if we misspelled :headers[c1] to :headers[d1] then it will not throw any exception and replace :headers[d1] with null.

那是因为 headers 只是一个 Map,如果没有这样的 键,你会得到 null 是事实 在地图上.为了克服这个错字问题,您可以使用带有 getter 的 POJO payload 或一些自定义标头,再次 - 带有 getter 的 POJO.在这种情况下,您最终会发现没有针对对象的此类属性.尽管您只会在运行时看到这个问题,而不是在编译时.Hashtable 也是如此——仅在运行时.

That's because the headers is just a Map and it's truth that you get null, if there is no such a key in the map. To overcome that typo issue you can use POJO payload with getters, or some custom header, and again - the POJO with getters. In this case you end up with exception that there is no such a property against object. Although you'll see that issue only at runtime, not on compile. And again the same is with Hashtable - only at runtime.

因此,我们必须使用 requires-reply="false" 来更改默认行为.

So, we have to use requires-reply="false" to change default behaviour.

你应该在设计时就明白:允许或不为组件返回任何内容.

You should understand it at design time: allow or not to return nothing for the component.

最后一个想法很好.您不介意分享您的 NullReplyAdvice 吗?实际上,我在 JDBC 网关之前使用 实现了相同的效果:通过 count(*) 查询确定是否有要获取的内容.当 SELECT 返回行时,我可以从那里引导我的流程到不同的逻辑,而不是直接流程.

The last idea is good. Wouldn't you mind to share your NullReplyAdvice? Actually I achieve the same with <filter> before the JDBC gateway: to determine if there is something to fetch by count(*) query. From there I can lead my flow to the different logic, rather than the direct flow, when SELECT returns rows.

更新

当您想使用 Model 对象在 Message 中保留特定于业务的值时,只需将此对象放在标题中即可:

When you want to use Model object to keep business-specific values within Message, it's just enough to put this object to the header:

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

这篇关于设计:Spring 集成 jdbc 最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆