Дизайн: Spring Integration jdbc най-добра практика

След като използвам 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> трябва да предадем всички контейнери (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>

Моля, поправете ме, ако има недостатъци в разбирането на концепцията.


person Vikas Sharma    schedule 27.06.2014    source източник


Отговори (1)


Трябва да погледнем напред и назад в кода на Java и xml файла за всяка промяна в условието where или когато има твърде много клаузи where.

Вярно е дори за необработения Java код около JDBC: ако промените модела, вие, разбира се, трябва да промените SELECT, защото това е просто низ. И затова има много работа, за да го направим безопасен за тип - ORM, QueryDSL, Spring-Data и т.н.

ако сме написали грешно :headers[c1] на :headers[d1], тогава няма да хвърли изключение и да замени :headers[d1] с null.

Това е така, защото headers е просто Map и е истина, че получавате null, ако няма такова key в картата. За да преодолеете този проблем с правописна грешка, можете да използвате POJO payload с гетери или някаква персонализирана заглавка и отново - POJO с гетери. В този случай завършвате с изключение, че няма такова свойство срещу обект. Въпреки че ще видите този проблем само по време на изпълнение, а не при компилиране. И отново същото е с Hashtable - само по време на изпълнение.

Така че трябва да използваме requires-reply="false", за да променим поведението по подразбиране.

Трябва да го разберете по време на проектиране: позволете или не да връщате нищо за компонента.

Последната идея е добра. Нямате ли нещо против да споделите вашето NullReplyAdvice? Всъщност постигам същото с <filter> преди JDBC шлюза: за да определя дали има нещо за извличане чрез count(*) заявка. Оттам мога да насоча своя поток към различната логика, а не към директния поток, когато SELECT връща редове.

АКТУАЛИЗАЦИЯ

Когато искате да използвате моделен обект, за да запазите специфични за бизнеса стойности в съобщението, достатъчно е да поставите този обект в заглавката:

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"/>
person Artem Bilan    schedule 09.07.2014
comment
За внедряване на NullReplyAdvice, моля, проверете forum.spring.io/forum/spring-projects/integration/ - person Vikas Sharma; 09.07.2014
comment
Проектът ми има твърде много запитвания и сега стана твърде многословен. Трябва да използвам NullReplyAdvice след всяка заявка, за да обработвам нулеви резултати. Можете ли да споделите кода на POJO полезен товар с гетъри. ще го пробвам Благодаря. - person Vikas Sharma; 10.07.2014
comment
Добавена проба за заглавка на POJO - person Artem Bilan; 10.07.2014
comment
В горния пример за заглавка на POJO, как да направите маршрутизиране въз основа на стойността на [foo].foo1. Например нещо подобно: ‹int:header-value-router input-channel=routingChannel header-name=:headers[foo].foo1› ‹int:mapping value=X channel=xChannel /› ‹int:mapping value= Y канал=yChannel /› ‹/int:header-value-router› - person Vikas Sharma; 10.07.2014
comment
Не, ‹header-value-router› просто извлича header по предоставено име. За тази вложена цел трябва да използвате общ рутер с expression="headers[foo].foo1". Забележка : индикаторът е само за JdbcTemplate - person Artem Bilan; 10.07.2014