【发布时间】:2015-02-19 21:53:48
【问题描述】:
我正在学习 Spring Core 认证,我对 Spring 如何处理 JDBC 查询有一些疑问:
所以我知道我可以根据我期望获得的数据类型以各种方式从我的数据库表中获取数据:
1) 查询简单类型(作为int、long或String):我使用jdbcTemplate的queryForObject()方法strong> 类,类似的东西:
String sql = "SELECT count(*) FROM T_REWARD";
int rowsNumber = jdbcTemplate.queryForObject(sql, Integer.class);
因此,为了获得一个简单的对象作为 int 值,我使用 queryForObject() 方法将 sql stattment 和我希望接收的对象类型传递给它方法的输出。
好的,这很简单,我认为没问题。
2) 查询放入 Map 对象的整个表行:所以如果我不需要单个值(可以放入特定的单个列中)表的行或类似前面的示例)我可以通过这些方式使用 queryForMap(..) 和 queryForList() 方法:
2.1) queryForMap():如果我希望将 单行 放入 单 Map 对象,其中每个列的值是映射到我的地图中,类似于:
String sql = "select * from T_REWARD where CONFIRMATION_NUMBER = ?";
Map<String, Object> values = jdbcTemplate.queryForMap(sql,confirmation.getConfirmationNumber());
2.2) queryForList():如果我期望更多行作为查询的输出,我会使用它。因此,我将获得一个Map 对象列表,其中每个 Map 对象代表查询输出的特定行。类似的东西:
String sql = “select * from PERSON”;
return jdbcTemplate.queryForList(sql);
我认为这也很清楚。
然后我可以使用 JdbcTemplate 将 ResultSet 映射到 域对象,这对我来说不是很清楚。
阅读文档被告知 JdbcTemplate 使用回调方法支持这一点。这种回调方法究竟是什么意思?
我知道 Spring 提供了一个 RowMapper 接口,用于将 ResultSet 的单行映射到对象:
public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNum)
throws SQLException;
}
我通过这种方法编写了以下示例,它使用新的 RestaurandRowMapper 对象作为 queryForObject() 方法的返回对象:
public Restaurant findByMerchantNumber(String merchantNumber) {
String sql = "select MERCHANT_NUMBER, NAME, BENEFIT_PERCENTAGE, BENEFIT_AVAILABILITY_POLICY from T_RESTAURANT where MERCHANT_NUMBER = ?";
return jdbcTemplate.queryForObject(sql, new RestaurantRowMapper(), merchantNumber);
还有这个内部类:
class RestaurantRowMapper implements RowMapper<Restaurant> {
public Restaurant mapRow(ResultSet rs, int i) throws SQLException {
return mapRestaurant(rs);
}
}
使用此私有方法创建映射:
private Restaurant mapRestaurant(ResultSet rs) throws SQLException {
// get the row column data
String name = rs.getString("NAME");
String number = rs.getString("MERCHANT_NUMBER");
Percentage benefitPercentage = Percentage.valueOf(rs.getString("BENEFIT_PERCENTAGE"));
// map to the object
Restaurant restaurant = new Restaurant(number, name);
restaurant.setBenefitPercentage(benefitPercentage);
restaurant.setBenefitAvailabilityPolicy(mapBenefitAvailabilityPolicy(rs));
return restaurant;
}
所以我很难理解所有这些东西是如何工作的。
我的主要疑问是:我知道使用 queryForObject() 方法作为输入参数传递给它,我期望作为输出的对象的类型(例如整数或长整数)。
如果我希望获得一个代表整行表的域对象(例如映射到 Restaurand 对象的 Restaurant 表 的一行),我想我应该使用这个对象(作为 Restaurant 对象),但在前面的示例中,我使用 **row mapper 对象 而不是 domain 对象:
return jdbcTemplate.queryForObject(sql, new RestaurantRowMapper(), merchantNumber);
这个内部类只包含返回预期的域对象
的mapRow()方法class RestaurantRowMapper implements RowMapper<Restaurant> {
public Restaurant mapRow(ResultSet rs, int i) throws SQLException {
return mapRestaurant(rs);
}
}
所以我认为 Spring 会自动调用 mapRow() 方法,该方法返回 Restaurand 域对象,该方法会自动替换为 queryForObject() 方法或类似的东西.但我不太确定它是否真的有效。
我错过了什么?你能解释一下后台到底发生了什么吗?
Tnx
【问题讨论】:
标签: java spring spring-jdbc jdbctemplate