AndreaNobili
AndreaNobili

Reputation: 42957

How exactly works this implementation of the query() method of the Spring JdbcTemplate?

I am working on a Spring application that use JdbcTemplate to query the database and I have some doubts about how exactly it works.

So, into a service class, I have this method definition that performs a query:

//JDBC TEMPLATE SELECT EXAMPLE 
public List<DBLog> queryAllLogs() {
    System.out.println("JDBCExample: queryAllLogs() is called");    

    final String QUERY_SQL = "SELECT * FROM LOG ORDER BY IDLOG";

    List<DBLog> dbLogList = this.jdbcTemplate.query(QUERY_SQL, new RowMapper<DBLog>() {

        public DBLog mapRow(ResultSet resulSet, int rowNum) throws SQLException {
            System.out.println("Getting log: "+ rowNum + " content: " + resulSet.getString("LOGSTRING"));

            DBLog dbLog = new DBLog();
            dbLog.setIDLOG(resulSet.getInt("IDLOG"));
            dbLog.setLOGSTRING(resulSet.getString("LOGSTRING"));
            return dbLog;
        }
    });
    return dbLogList; 
}

This method simply perform a query that return all the records inside a LOG table orderd by the IDLOG field value. This is pretty simple to understand.

Reading on the official documentation I found that this implementation of the query() method take 2 objects: the query string and a RowMapper object and that:

Query using a prepared statement, mapping each row to a Java object via a RowMapper

So I think that the QUERY_SQL query String is automatically converted into a PreparedStatment by the query() method implementation (is it right or am I missing something?)

The thing that is absolutly not clear for me is that it seems to me that in the previous example, I am defining a RowMapper implementation as second parameter of the query method.

So this specific implemention contain the mapRow(ResultSet resulSet, int rowNum) method implementation that from what I have understand is called for each row of the ResultSet object returned by the query execution. So this method will automatically map a specific row on a DBLog that will be automatically added to the returned List<DBLog> dbLogList list.

Is it my reasoning correct or am I missing something?

Who do all this work? Is it this specific query() method implementation (the one that take these 2 specific input parameter) that take care to call the mapRow() method of the passed RowMapper object and then add the returned DBLog object to the list?

Upvotes: 2

Views: 1780

Answers (1)

Tunaki
Tunaki

Reputation: 137064

Your reasoning is entirely correct.

First, take a look at this table in the documentation. It lists everything that Spring JDBC automatically does and what you are left to do. Basically, all you need to do when using Spring JDBC is:

  • setting up the JDBC connection
  • specify the SQL statement to execute
  • provide parameters value if there are parameters
  • for each result, do the work of converting the result to an object

JDBCTemplate.query(String, RowMapper) follows the same pattern. First, you give it a SQL statement to execute: this is the first parameter (point 2 of the list above). Second, you give it an object which will be responsible for translating each result into your domain object (point 4 of the list above).

This object is called a RowMapper because it maps rows of a database, represented by a ResultSet object, into your domain object.

This is one of the main advantage of using Spring JDBC over raw JDBC: it factors out all the common and repeating tasks into its core. Yes, it will use a PreparedStatement under the hood, that is going to be executed and the ResultSet will be looped over. And in each iteration of this loop (made by Spring JDBC), your RowMapper will be called. Its result will be aggregated into a List by Spring JDBC and finally returned.

Upvotes: 1

Related Questions