In this lab you will gain experience with Spring’s JDBC
simplification. You will use a JdbcTemplate
to execute SQL statements with
JDBC.
What you will learn:
Specific subjects you will gain experience with:
JdbcTemplate
classEstimated time to complete: 45 minutes
Quick instructions for this exercise have been embedded within
the lab materials in the form of TODO comments. To display them,
open the Tasks
view (Window >> Show View >>
Tasks (not Task
List)).
The goal for this lab is to refactor the existing JDBC based
repositories from their standard try, catch, finally, try, catch
paradigm to using Spring’s JdbcTemplate
. The first repository to
refactor will be the JdbcRewardRepository
. This repository is the
easiest to refactor and will serve to illustrate some of the key
features available because of Spring’s simplification.
(TODO-01) Before making any changes to JdbcRewardRepository
, let’s first
ensure the existing functionality works by implementing a test.
Open JdbcRewardRepositoryTests
in the
rewards.internal.reward
package and
notice the getRewardCount() method. In this method use the jdbcTemplate
included in the test fixture to
query for the number of rows in the T_REWARD
table
and return it.
(TODO-02) In the same class, find the
verifyRewardInserted(RewardConfirmation, Dining) method. In this
method, use the jdbcTemplate
to query
for a map of all values in the T_REWARD
table based on the confirmationNumber
of the RewardConfirmation
. The column name to use
for the confirmationNumber
in the
where clause is CONFIRMATION_NUMBER
.
Finally run the test class. When you have the green bar, move on to the next step.
(TODO-03) We are now going to refactor an existing Repository
class so it can use the JdbcTemplate
.
To start find the JdbcRewardRepository
in the rewards.internal.reward
package. Open the class and add a private field to it of type JdbcTemplate
. In the constructor,
instantiate the JdbcTemplate
and
assign it to the field you just created.
Next refactor the nextConfirmationNumber() method to use the
JdbcTemplate
. This refactoring is a
good candidate for using the queryForObject(String, Class<T>,
Object…) method.
Tip | |
---|---|
The |
Next refactor the confirmReward(AccountContribution, Dining) method to use the template. This refactoring is a good candidate for using the update(String, Object…) method.
Once you have completed these changes, run the test class again
(JdbcRewardRepositoryTests
) to ensure
these changes work as expected. When you have the green bar, move
on to the next step.
(TODO-04) In many cases, you’ll want to return complex
objects from calls to the database. To do this you’ll need to
tell the JdbcTemplate
how to map a
single ResultSet row to an object. In this step, you’ll
refactor JdbcRestaurantRepository
using a RowMapper
to create Restaurant
objects.
Before making any changes, run the JdbcRestaurantRepositoryTests
class to
ensure that the existing implementation functions correctly. When
you have the green bar, move on to the next step.
Next, find the JdbcRestaurantRepository
in the rewards.internal.restaurant
package. Open
this class and again modify it so that it has a JdbcTemplate
field.
Time to refactor the findByMerchantNumber(String)
method to use
the template.
Create a private inner class called RestaurantRowMapper
that implements the
RowMapper
interface. Note that this
interface has a generic type parameter that should be populated in
the implementation.
If you’ve implemented the interface correctly, the class
and method declarations should look like Figure 1. The
implementation of the mapRow(ResultSet,
int)
method should delegate to the mapRestaurant(ResultSet)
method.
RestaurantRowMapper
class and method
declaration.
private class RestaurantRowMapper implements RowMapper<Restaurant> {
public Restaurant mapRow(ResultSet rs, int rowNum) throws SQLException {
return mapRestaurant(rs);
}
}
Now refactor the findByMerchantNumber(String)
method to use
the template. This refactoring is a good candidate for using the
queryForObject(String, RowMapper<T>,
Object…)
method.
Note | |
---|---|
If you prefer to use a lambda instead please do so. Have it
delegate to the existing |
Finally run the JdbcRestaurantRepositoryTests
class. When
you have the green bar, move on to the next step.
In this repository there are two different methods that need to
be refactored: updateBeneficiaries(Account)
and findByCreditCard(String)
.
Only do this section if you have enough time left. You will need 10-15 mins.
Before making any changes run the JdbcAccountRepositoryTests
class to ensure
the existing implementation functions properly. When you have the
green bar, move on.
(TODO-05) Next find the JdbcAccountRepository
in the rewards.internal.account
package. Open this
class and again modify it so that it has a field of type JdbcTemplate
.
(TODO-06) Start by refactoring the updateBeneficiaries(Account)
method to use the JdbcTemplate
. This
refactoring is very similar to the one that you did earlier for the
JdbcRewardRepository
.
When you are done, rerun the JdbcAccountRepositoryTests
tests. When you
have the green bar, you are good.
This is an optional step if you have at least 10 minutes of the lab remaining.
(TODO-07) Sometimes when doing complex joins in a query
you’ll need to have access to an entire result set instead of
just a single row of a result set to build a complex object. To do
this you’ll need to tell the JdbcTemplate
that you’d like full
control over ResultSet extraction.
In this step you’ll refactor findByCreditCard(String)
using a ResultSetExtractor to create Account
objects.
Create a private inner class called AccountExtractor
that implements the
ResultSetExtractor interface. Note that this interface also has a
generic type parameter that should be populated. The implementation
of the extractData(ResultSet) method should delegate to the
existing mapAccount(ResultSet) method.
Note | |
---|---|
If you prefer to use a lambda instead please do so. Have it
delegate to the existing |
Next refactor the findByCreditCard(String)
method to use the
template. This refactoring is a good candidate for using the query(String, ResultSetExtractor<T>,
Object…)
method.
Finally run the JdbcAccountRepositoryTests
tests once again.
When you have the green bar, you’ve completed the lab!
Tip | |
---|---|
Note that all three repositories still have a |