Spring Batch3

ItemReaders and ItemWriters in Spring Batch 2.0

<div dir&equals;"ltr" style&equals;"text-align&colon; justify&semi;">&NewLine;<h2><b>ItemReader-<&sol;b><&sol;h2>&NewLine;<p>Although a simple concept&comma; an <i><b>ItemReader <&sol;b><&sol;i>is the means for providing data from many different types of input&period; The most general examples include&colon;<&sol;p>&NewLine;<div class&equals;"itemizedlist">&NewLine;<ul >&NewLine;<li>Flat File- Flat File Item Readers read lines of data from a flat file that typically describe records with fields of data defined by fixed positions in the file or delimited by some special character &lpar;e&period;g&period; Comma&rpar;&period;<&sol;li>&NewLine;<li>XML &&num;8211&semi; XML <i><b>ItemReaders <&sol;b><&sol;i>process XML independently of technologies used for parsing&comma; mapping and validating objects&period; Input data allows for the validation of an XML file against an XSD schema&period;<&sol;li>&NewLine;<li>Database &&num;8211&semi; A database resource is accessed to return resultsets which can be mapped to objects for processing&period; The default SQL <i><b>ItemReaders <&sol;b><&sol;i>invoke a <b><i>RowMapper <&sol;i><&sol;b>to return objects&comma; keep track of the current row if restart is required&comma; store basic statistics&comma; and provide some transaction enhancements that will be explained later&period;<&sol;li>&NewLine;<&sol;ul>&NewLine;<&sol;div>&NewLine;<p>There are many more possibilities&comma; but we&&num;8217&semi;ll focus on the basic ones for this chapter&period; A complete list of all available <i><b>ItemReaders <&sol;b><&sol;i>can be found in Appendix A&period;<br &sol;>&NewLine;<i><b>ItemReader <&sol;b><&sol;i>is a basic interface for generic input operations&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">public interface ItemReader&lt&semi;T&gt&semi; &lbrace; &NewLine; &NewLine; T read&lpar;&rpar; throws Exception&comma; UnexpectedInputException&comma; ParseException&semi; &NewLine; &NewLine;&rcub; &NewLine;<&sol;pre>&NewLine;<div id&equals;"ads-id" align&equals;"center"><&sol;div>&NewLine;<p>The read method defines the most essential contract of the <i><b>ItemReader<&sol;b><&sol;i>&semi; calling it returns one Item or null if no more items are left&period; An item might represent a line in a file&comma; a row in a database&comma; or an element in an XML file&period; It is generally expected that these will be mapped to a usable domain object &lpar;i&period;e&period; Trade&comma; Foo&comma; etc&rpar; but there is no requirement in the contract to do so&period;<&sol;p>&NewLine;<p>It is expected that implementations of the <i><b>ItemReader <&sol;b><&sol;i>interface will be forward only&period; However&comma; if the underlying resource is transactional &lpar;such as a JMS queue&rpar; then calling read may return the same logical item on subsequent calls in a rollback scenario&period; It is also worth noting that a lack of items to process by an <i><b>ItemReader <&sol;b><&sol;i>will not cause an exception to be thrown&period; For example&comma; a database <i><b>ItemReader <&sol;b><&sol;i>that is configured with a query that returns 0 results will simply return null on the first invocation of read&period;<&sol;p>&NewLine;<h2><b>ItemWriter-<&sol;b><&sol;h2>&NewLine;<p><i><b>ItemWriter <&sol;b><&sol;i>is similar in functionality to an <i><b>ItemReader<&sol;b><&sol;i>&comma; but with inverse operations&period; Resources still need to be located&comma; opened and closed but they differ in that an <i><b>ItemWriter <&sol;b><&sol;i>writes out&comma; rather than reading in&period; In the case of databases or queues these may be inserts&comma; updates&comma; or sends&period; The format of the serialization of the output is specific to each batch job&period;<&sol;p>&NewLine;<p>As with <i><b>ItemReader<&sol;b><&sol;i>&comma; <b><i>ItemWriter <&sol;i><&sol;b>is a fairly generic interface&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">public interface ItemWriter&lt&semi;T&gt&semi; &lbrace; &NewLine; &NewLine; void write&lpar;List&lt&semi;&quest; extends T&gt&semi; items&rpar; throws Exception&semi; &NewLine; &NewLine;&rcub; &NewLine;<&sol;pre>&NewLine;<p>As with read on <i><b>ItemReader<&sol;b><&sol;i>&comma; write provides the basic contract of <i><b>ItemWriter<&sol;b><&sol;i>&semi; it will attempt to write out the list of items passed in as long as it is open&period; Because it is generally expected that items will be &&num;8216&semi;batched&&num;8217&semi; together into a chunk and then output&comma; the interface accepts a list of items&comma; rather than an item by itself&period; After writing out the list&comma; any flushing that may be necessary can be performed before returning from the write method&period; For example&comma; if writing to a Hibernate DAO&comma; multiple calls to write can be made&comma; one for each item&period; The writer can then call close on the hibernate Session before returning&period;<&sol;p>&NewLine;<h2><b>ItemProcessor-<&sol;b><&sol;h2>&NewLine;<p>The <i><b>ItemReader <&sol;b><&sol;i>and <i><b>ItemWriter <&sol;b><&sol;i>interfaces are both very useful for their specific tasks&comma; but what if you want to insert business logic before writing&quest; One option for both reading and writing is to use the composite pattern&colon; create an <i><b>ItemWriter <&sol;b><&sol;i>that contains another <b><i>ItemWriter<&sol;i><&sol;b>&comma; or an <i><b>ItemReader <&sol;b><&sol;i>that contains another <i><b>ItemReader<&sol;b><&sol;i>&period; For example&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">public class CompositeItemWriter&lt&semi;T&gt&semi; implements ItemWriter&lt&semi;T&gt&semi; &lbrace; &NewLine; &NewLine; ItemWriter&lt&semi;T&gt&semi; itemWriter&semi; &NewLine; &NewLine; public CompositeItemWriter&lpar;ItemWriter&lt&semi;T&gt&semi; itemWriter&rpar; &lbrace; &NewLine; this&period;itemWriter &equals; itemWriter&semi; &NewLine; &rcub; &NewLine; &NewLine; public void write&lpar;List&lt&semi;&quest; extends T&gt&semi; items&rpar; throws Exception &lbrace; &NewLine; &sol;&sol;Add business logic here &NewLine; itemWriter&period;write&lpar;item&rpar;&semi; &NewLine; &rcub; &NewLine; &NewLine; public void setDelegate&lpar;ItemWriter&lt&semi;T&gt&semi; itemWriter&rpar;&lbrace; &NewLine; this&period;itemWriter &equals; itemWriter&semi; &NewLine; &rcub; &NewLine;&rcub; &NewLine;<&sol;pre>&NewLine;<p>The class above contains another <b><i>ItemWriter <&sol;i><&sol;b>to which it <i><b>delegates<&sol;b><&sol;i> after having provided some business logic&period; This pattern could easily be used for an <i><b>ItemReader <&sol;b><&sol;i>as well&comma; perhaps to obtain more reference data based upon the input that was provided by the main <i><b>ItemReader<&sol;b><&sol;i>&period; It is also useful if you need to control the call to write yourself&period; However&comma; if you only want to &&num;8216&semi;transform&&num;8217&semi; the item passed in for writing before it is actually written&comma; there isn&&num;8217&semi;t much need to call write yourself&colon; you just want to modify the item&period; For this scenario&comma; Spring Batch provides the <b><i>ItemProcessor <&sol;i><&sol;b>interface&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">public interface ItemProcessor&lt&semi;I&comma; O&gt&semi; &lbrace; &NewLine; &NewLine; O process&lpar;I item&rpar; throws Exception&semi; &NewLine;&rcub; &NewLine;<&sol;pre>&NewLine;<p>An <b><i>ItemProcessor <&sol;i><&sol;b>is very simple&semi; given one object&comma; transform it and return another&period; The provided object may or may not be of the same type&period; The point is that business logic may be applied within process&comma; and is completely up to the developer to create&period; An <i><b>ItemProcessor <&sol;b><&sol;i>can be wired directly into a step&comma; For example&comma; assuming an <i><b>ItemReader <&sol;b><&sol;i>provides a class of type Foo&comma; and it needs to be converted to type Bar before being written out&period; An <i><b>ItemProcessor <&sol;b><&sol;i>can be written that performs the conversion&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">public class Foo &lbrace;&rcub; &NewLine; &NewLine;public class Bar &lbrace; &NewLine; public Bar&lpar;Foo foo&rpar; &lbrace;&rcub; &NewLine;&rcub; &NewLine; &NewLine;public class FooProcessor implements ItemProcessor&lt&semi;Foo&comma;Bar&gt&semi;&lbrace; &NewLine; public Bar process&lpar;Foo foo&rpar; throws Exception &lbrace; &NewLine; &sol;&sol;Perform simple transformation&comma; convert a Foo to a Bar &NewLine; return new Bar&lpar;foo&rpar;&semi; &NewLine; &rcub; &NewLine;&rcub; &NewLine; &NewLine;public class BarWriter implements ItemWriter&lt&semi;Bar&gt&semi;&lbrace; &NewLine; public void write&lpar;List&lt&semi;&quest; extends Bar&gt&semi; bars&rpar; throws Exception &lbrace; &NewLine; &sol;&sol;write bars &NewLine; &rcub; &NewLine;&rcub; &NewLine;<&sol;pre>&NewLine;<p><i><b>I<&sol;b><&sol;i>n the very simple example above&comma; there is a class Foo&comma; a class Bar&comma; and a class <i><b>FooProcessor <&sol;b><&sol;i>that adheres to the <i><b>ItemProcessor <&sol;b><&sol;i>interface&period; The transformation is simple&comma; but any type of transformation could be done here&period; The <i><b>BarWriter <&sol;b><&sol;i>will be used to write out Bar objects&comma; throwing an exception if any other type is provided&period; Similarly&comma; the <i><b>FooProcessor <&sol;b><&sol;i>will throw an exception if anything but a Foo is provided&period; The <i><b>FooProcessor <&sol;b><&sol;i>can then be injected into a Step&colon;<&sol;p>&NewLine;<pre class&equals;"highlight">&lt&semi;job id&equals;"ioSampleJob"&gt&semi; &NewLine; &lt&semi;step name&equals;"step1"&gt&semi; &NewLine; &lt&semi;tasklet&gt&semi; &NewLine; &amp&semi;lt&semi;chunk reader&equals;"fooReader" processor&equals;"fooProcessor" writer&equals;"barWriter" &NewLine; commit-interval&equals;"2"&sol;&amp&semi;gt&semi; &NewLine; &lt&semi;&sol;tasklet&gt&semi; &NewLine; &lt&semi;&sol;step&gt&semi; &NewLine;&lt&semi;&sol;job&gt&semi; &NewLine;<&sol;pre>&NewLine;<p><b>&lt&semi;&lt&semi;<a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;configuring-step-in-spring-batch-2&sol;">Configuring Step in Spring Batch<&sol;a>&lt&semi;&lt&semi; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;spring-tutorial&sol;">Index <&sol;a>&gt&semi;&gt&semi; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;scaling-and-parallel-processing-in&sol;">Scaling and Parallel Processing<&sol;a>&gt&semi;&gt&semi;<&sol;b><&sol;p>&NewLine;<&sol;div>&NewLine;<div class&equals;"wp-post-navigation"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <div class&equals;"wp-post-navigation-pre"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;the-domain-language-of-batch&sol;">Previous<&sol;a> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <&sol;div> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <div class&equals;"wp-post-navigation-next"> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <a href&equals;"https&colon;&sol;&sol;dineshonjava&period;com&sol;configuring-and-running-job-in-spring&sol;">Next<&sol;a> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab; <&sol;div> &NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;<&sol;div>&NewLine;<script type&equals;"text&sol;javascript">&NewLine;jQuery&lpar;document&rpar;&period;ready&lpar;function&lpar;&dollar;&rpar; &lbrace;&NewLine; &dollar;&period;post&lpar;'https&colon;&sol;&sol;dineshonjava&period;com&sol;wp-admin&sol;admin-ajax&period;php'&comma; &lbrace;action&colon; 'mts&lowbar;view&lowbar;count'&comma; id&colon; '609'&rcub;&rpar;&semi;&NewLine;&rcub;&rpar;&semi;&NewLine;<&sol;script>

Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design PatternsĀ using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

4 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

4 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

4 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

4 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

4 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

4 years ago