52

I worked on both row mapper and resultset extractor call back interfaces.I found difference i.e.,

1.Row mapper can be processing per row basis.But Resultset extractor we can naviagte all rows and return type is object.

Is there any difference other than above?.How the works Rowmapper internal and return type is list?.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
user1127214
  • 3,109
  • 7
  • 26
  • 30
  • 1
    In my opinion, RowMapper is a lot simpler and you probably will end up using it rather than ResultSetExtractor. But for more info check out the [JavaDoc](http://static.springsource.org/spring/docs/3.0.0.RC1/javadoc-api/) and the [Documentation](http://static.springsource.org/spring/docs/2.5.x/reference/jdbc.html) – Zack Apr 09 '12 at 13:45

4 Answers4

53

Basic difference is with ResultsetExtractor you will need to iterate through the result set yourself, say in while loop. This interface provides you processing of the entire ResultSet at once. The implemetation of Interface method extractData(ResultSet rs) will contain that manual iteration code. See one implementation of ResultsetExtractor

while some callback handlers like RowCallbackHandler, the interface method processRow(ResultSet rs) loops for you.

RowMapper can be used both was for mapping each row, or entire rows.

For entire rows Object (by template method jdbcTemplate.query())

 public List findAll() {    
    String sql = "SELECT * FROM EMPLOYEE";
    return jdbcTemplate.query(sql, new EmployeeRowMapper());
} 
without casting will work

For individual object (with Template method jdbcTemplate.queryForObject())

@SuppressWarnings({ "unchecked", "rawtypes" })
public Employee findById(int id) {
    String sql = "SELECT * FROM EMPLOYEE WHERE ID = ?";
//  jdbcTemplate = new JdbcTemplate(dataSource);

    Employee employee = (Employee) jdbcTemplate.queryForObject(sql,  new EmployeeRowMapper(), id );

    // Method 2 very easy
    //  Employee employee = (Employee) jdbcTemplate.queryForObject(sql, new Object[] { id }, new BeanPropertyRowMapper(Employee.class));

    return employee;
}

@SuppressWarnings("rawtypes")
public class EmployeeRowMapper implements RowMapper {

public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    Employee employee = new Employee();
    employee.setId(rs.getInt("ID"));
    employee.setName(rs.getString("NAME"));
    employee.setAge(rs.getInt("AGE"));
    return employee;
}

}

Best Use cases:

Row Mapper: When each row of a ResultSet maps to a domain Object, can be implemented as private inner class.

RowCallbackHandler: When no value is being returned from callback method for each row, e.g. writing row to a file, converting rows to a XML, Filtering rows before adding to collection. Very efficient as ResultSet to Object mapping is not done here.

ResultSetExtractor: When multiple rows of ResultSet map to a single Object. Like when doing complex joins in a query one may need to have access to entire ResultSet instead of single row of rs to build complex Object and you want to take full control of ResultSet. Like Mapping the rows returned from the join of TABLE1 and TABLE2 to an fully-reconstituted TABLE aggregate.

ParameterizedRowMapper is used to create complex objects

vimal krishna
  • 2,886
  • 28
  • 22
35

JavaDoc of ResultSetExtractor:

This interface is mainly used within the JDBC framework itself. A RowMapper is usually a simpler choice for ResultSet processing, mapping one result object per row instead of one result object for the entire ResultSet.

ResultSetExtractor is suppose to extract the whole ResultSet (possibly multiple rows), while RowMapper is feeded with row at a time.

Most the time, ResultSetExtractor will loop the ResultSet and use RowMapper, snippet example of Spring RowMapperResultSetExtractor:

List<T> results = (this.rowsExpected > 0 ? new ArrayList<T>(this.rowsExpected) : new ArrayList<T>());
int rowNum = 0;
while (rs.next()) {
    results.add(this.rowMapper.mapRow(rs, rowNum++));
}
return results;

Pay attention, ALL results will be transformed, this can create Out Of Memory exception.

See also

Thomas Decaux
  • 21,738
  • 2
  • 113
  • 124
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 9
    ResultSetExtractor has uses outside the framework, for example it is useful for mapping a one to many using a single SQL statement, for example an Employee with a set of Holidays. – Jasper Blues Mar 31 '15 at 09:53
  • But RowMapper and ResultSetExtractor can be used for fetching List of records?? – susan097 May 30 '18 at 12:53
3

RowMapper: To process one record of ResultSet at a time.

ResultSetExtractor: To process multiple records of ResultSet at a time.

arqam
  • 3,582
  • 5
  • 34
  • 69
0

I think one place where a ResultSetExtractor could be advantageous is when you have a result set (like from a call to a stored procedure) and a row mapper, and want to process them like is done under the covers in the jdbcTemplate methods, such as query(String sql, RowMapper rowMapper). In this case you can save yourself from having to manually iterate over the result set by using the ResultSetExtractor instead of just the RowMapper.

For example:

RowMapper

ResultSet resultSet = cs.executeQuery();
int row = 0;
DateRowMapper dateRowMapper = new DateRowMapper();
List<String> dates = new ArrayList<>();
while (resultSet.next()) {
    dates.add(dateRowMapper.mapRow(resultSet, ++row));
}
return dates;

ResultSetExtractor

ResultSet resultSet = callableStatement.executeQuery();
return new RowMapperResultSetExtractor<>(new DateRowMapper()).extractData(resultSet);
Togepi
  • 63
  • 1
  • 4
MMW
  • 71
  • 1
  • 1
  • 3