Getting Started With Spring Batch 2.0
Storing Items Into a Database
Here's the playerWriter bean we referenced from the playerLoad step:
<beans:bean id="playerWriter" class="org.springframework.batch.sample.domain.
football.internal.PlayerItemWriter">
<beans:property name="playerDao">
<beans:bean class="org.springframework.batch.sample.domain.football.
internal.JdbcPlayerDao">
<beans:property name="dataSource" ref="dataSource" />
</beans:bean>
</beans:property>
</beans:bean>
The PlayerItemWriter is a custom class, though it turns out that it's pretty trivial as listing 4 shows.
package org.springframework.batch.sample.domain.football.internal;
import java.util.List;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.sample.domain.football.Player;
import org.springframework.batch.sample.domain.football.PlayerDao;
public class PlayerItemWriter implements ItemWriter<Player> {
private PlayerDao playerDao;
public void setPlayerDao(PlayerDao playerDao) {
this.playerDao = playerDao;
}
public void write(List<? extends Player> players) throws Exception {
for (Player player : players) {
playerDao.savePlayer(player);
}
}
There isn't anything special happening here. The step will use the FlatFileItemReader to pull items from a flat file and will pass them in chunks to the PlayerItemWriter, which dutifully saves them to the database.
The examples we've seen so far are among the simplest possible, but the general idea behind ItemReaders and ItemWriters should be clear now: readers pull items from an arbitrary data source and map them to domain objects, whereas writers map domain objects to items in a data sink. But just for good measure, let's take a look at one more ItemReader.
JdbcCursorItemReader
The JdbcCurstorItemReader allows us to pull items from a database. In the case of the football job, we're using the JdbcCursorItemReader to pull player and game data from the database so that we can synthesize them into PlayerSummary domain objects, which we'll subsequently write. At any rate here's the definition for our playerSummarizationSource, which is part of the job's third step:
<beans:bean id="playerSummarizationSource"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="rowMapper">
<beans:bean class="org.springframework.batch.sample.domain.football.
internal.PlayerSummaryMapper" />
</beans:property>
<beans:property name="sql">
<beans:value>
SELECT games.player_id, games.year_no, SUM(COMPLETES),
SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD),
SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS),
SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD)
from games, players where players.player_id =
games.player_id group by games.player_id, games.year_no
</beans:value>
</beans:property>
</beans:bean>
The sql property as you might guess provides the SQL used to pull data from the data source. Here we're using both the players and games tables to compute player stats. The result of that query is a JDBC ResultSet, which this particular ItemReader implementation passes to a RowMapper implementation. The PlayerSummaryMapper is a custom implementation, and it essentially takes a row in a ResultSet and carries it to a PlayerSummary domain object.
Summary
With that we conclude our introductory tour of Spring Batch 2.0. We've only scratched the surface, showing how to create simple jobs with simple sequential steps, and how to run them.
Once you feel comfortable with simple jobs, it makes sense to spend a little time with the introductory chapters of the Spring Batch Reference Documentation to learn more about the execution environment, including the difference between Jobs, JobInstances and JobExcecutions. You can use Spring Batch in conjunction with a scheduler (such as Quartz) to run batch jobs on a recurring basis in an automated fashion.
More advanced topics include non-sequential step flow, such as conditional flows and parallel flows, and support for partitioning individual steps across multiple threads or even servers.
Enjoy!
Willie is an IT director with 12 years of Java development experience. He and his brother John are coauthors of the upcoming book Spring in Practice by Manning Publications (www.manning.com/wheeler/). Willie also publishes technical articles (including many on Spring) to wheelersoftware.com/articles/.
- Login or register to post comments
- 37239 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
gzres replied on Wed, 2009/03/25 - 2:59am
Matthew Schmidt replied on Wed, 2009/03/25 - 6:30am
Matthew Schmidt replied on Wed, 2009/03/25 - 9:33am
in response to: gzres
gzres replied on Thu, 2009/03/26 - 5:17am
in response to: matt
hksduhksdu replied on Wed, 2009/04/01 - 12:38am
While SpringFramework team has done a great job, I would rather go with BPM. Basically you can manage your BPM with scheduler or in sequence of events. Besides, it is easy to make changes to business rules where sticking with batch means to going back to COBOL+JCL Java version?
I've played with NetBeans' BPEL plugin and I think it's awesome! I think I can spare more time on data schema validations and requirement verifications than pure coding to end of the world for batch processing.
Just my 2 cents though,
:)
tariqahsan replied on Wed, 2009/05/06 - 10:13am
Declan Cox replied on Tue, 2009/08/25 - 5:22am
sunrise1 replied on Fri, 2009/10/23 - 5:45am
Kevin321 replied on Fri, 2009/11/13 - 5:27am