As you can see, to configure your JdbcPagingItemReader, you provide it a datasource,
PagingQueryProvider, the parameters to be injected into your SQL, the size of each page, and the
RowMapper implementation that will be used to map your results.
Within the PagingQueryProvider's configuration, you provide five pieces of information. The first
three are the different pieces of your SQL statement: the select clause, the from clause, and the where
clause of your statement. The next property you set is the sort key. It is important to sort your results
when paging since instead of a single query being executed and the results being streamed, a paged
approach will typically execute a query for each page. In order for the record order to be guaranteed
across query executions, an order by is recommended and is applied to the generated SQL statement for
any fields that are listed in the sortKey. Finally, you have a dataSource reference. You may wonder why
you need to configure it in both the SqlPagingQueryProviderFactoryBean and the
JdbcPagingItemReader. The SqlPagingQueryProviderFactoryBean uses the dataSource to determine
what type of database it's working with. From there, it provides the appropriate implementation of the
PagingQueryProvider to be used for your reader.
The use of parameters in a paging context is different than it is in the previous cursor example.
Instead of creating a single SQL statement with question marks as parameter placeholders, you build
your SQL statement in pieces. Within the whereClause string, you have the option of using either the
standard question mark placeholders or you can use the named parameters as I did in the
customerItemReader in Listing 7-42. From there, you can inject the values to be set as a map in your
configuration. In this case, the city entry in the parameterValues map maps to the named parameter city
in your whereClause string. If you wanted to use question marks instead of names, you would use the
number of the question mark as the key for each parameter. With all of the pieces in place, Spring Batch
will construct the appropriate query for each page each time it is required.
As you can see, straight JDBC interaction with a database for reading the items to be processed is
actually quite simple. With not much more than a few lines of XML, you can have a performant
ItemReader in place that allows you to input data to your job. However, JDBC isn't the only way to
access database records. Object Relational Mapping (ORM) technologies like Hibernate and MyBatis
have become popular choices for data access given their well-executed solution for mapping relational
database tables to objects. You will take a look at how to use Hibernate for data access next.
Hibernate is the leading ORM technology in Java today. Written by Gaven King back in 2001, Hibernate
provides the ability to map the object oriented model you use in your applications to a relational
database. Hibernate uses XML files or annotations to configure mappings of objects to database tables; it
also provides a framework for querying the database by object. This provides the ability to write queries
based on the object structure with little or no knowledge of the underlying database structure. In this
section, you will look at how to use Hibernate as your method of reading items from a database.
Using Hibernate in batch processing is not as straightforward as it is for web applications. For web
applications, the typical scenario is to use the session in view pattern. In this pattern, the session is
opened as a request comes into the server, all processing is done using the same session, and then the
session is closed as the view is returned to the client. Although this works well for web applications that
typically have small independent interactions, batch processing is different.
For batch processing, if you use Hibernate naively, you would use the normal stateful session
implementation, read from it as you process your items, and write to it as you complete your processing
closing the session once the step is complete. However, as mentioned, the standard session within