The Goal

We’re going to implement generic methods that take a SQL query and mapper as parameters and return a Java object and List of objects. Assuming that we already have the code that does all db connection related things - this is out of scope for the post.

Generic Methods

The methods will be

public <T> T queryForObject(String sql, RowMapper<T> mapper) {
    return jdbcTemplate.queryForObject(sql, mapper);
}
public <T> List<T> queryForList(String sql, RowMapper<T> mapper) {
    return jdbcTemplate.query(sql, mapper);
}

RowMapper

This is an example for a product item.

public class ProductItemRowMapper implements RowMapper<ProductItem> {

    @Override
    public ProductItem mapRow(ResultSet rs, int rowNum) throws SQLException {

        ProductItem item = new ProductItem();
        item.setId(rs.getLong("ID"));
        item.setTitle(rs.getString("TITLE"));
        item.setDescription(rs.getString("DESCRIPTION"));
        item.setPrice(rs.getDouble("PRODUCT_PRICE"));
        item.setAvailable(rs.getBoolean("AVAILABLE"));

        return item;
    }
}

You can call the methods now

ProductItem productItem = queryForObject(sql, new ProductItemRowMapper());
List<ProductItem> productItems = queryForList(sql, new ProductItemRowMapper());

I’ve also seen some people incapsulate RowMapper into the ProductItem class like that

public class ProductItem {

    private long id;
    private String title;
    private String description;
    private Double price;
    private boolean available;

    public ProductItem() {
    }

    public static RowMapper<ProductItem> getMapper() {
        return new RowMapper<ProductItem>() {
            @Override
            public ProductItem mapRow(ResultSet rs, int rowNum) throws SQLException {
                ProductItem item = new ProductItem();
                item.setId(rs.getLong("ID"));
                item.setTitle(rs.getString("TITLE"));
                item.setDescription(rs.getString("DESCRIPTION"));
                item.setPrice(rs.getDouble("PRODUCT_PRICE"));
                item.setAvailable(rs.getBoolean("AVAILABLE"));
                return item;
            }
        };
    }
    ...
   // Setters and Getters
}

In this case your calls will be

ProductItem productItem = queryForObject(sql, ProductItem.getMapper());
List<ProductItem> productItems = queryForList(sql, ProductItem.getMapper());