您还可以使用 ResultSetExtractor
而不是 RowMapper
。两者都像彼此一样简单,唯一的区别是你调用ResultSet.next()
。
public String test() {
String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN "
+ " where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
return jdbc.query(sql, new ResultSetExtractor<String>() {
@Override
public String extractData(ResultSet rs) throws SQLException,
DataAccessException {
return rs.next() ? rs.getString("ID_NMB_SRZ") : null;
}
});
}
ResultSetExtractor
具有额外的好处,即您可以处理返回多行或未返回任何行的所有情况。
更新:几年过去了,我有一些技巧可以分享。JdbcTemplate
与java 8 lambdas配合得非常好,以下示例就是为之设计的,但你可以很容易地使用静态类来实现相同的目标。
虽然问题与简单类型有关,但这些示例可作为提取域对象的常见情况的指南。
首先。为简单起见,假设您有一个具有两个属性的帐户对象。您可能希望有一个 for this domain 对象。Account(Long id, String name)
RowMapper
private static final RowMapper<Account> MAPPER_ACCOUNT =
(rs, i) -> new Account(rs.getLong("ID"),
rs.getString("NAME"));
现在,您可以直接在方法中使用此映射器来映射查询中的域对象(是一个实例)。Account
jt
JdbcTemplate
public List<Account> getAccounts() {
return jt.query(SELECT_ACCOUNT, MAPPER_ACCOUNT);
}
很好,但是现在我们想要我们原来的问题,我们使用我的原始解决方案重用RowMapper
来为我们执行映射。
public Account getAccount(long id) {
return jt.query(
SELECT_ACCOUNT,
rs -> rs.next() ? MAPPER_ACCOUNT.mapRow(rs, 1) : null,
id);
}
很好,但这是您可能并且希望重复的模式。因此,您可以创建一个泛型工厂方法来为任务创建新的 ResultSetExtractor
。
public static <T> ResultSetExtractor singletonExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? mapper.mapRow(rs, 1) : null;
}
创建 ResultSetExtractor
现在变得微不足道。
private static final ResultSetExtractor<Account> EXTRACTOR_ACCOUNT =
singletonExtractor(MAPPER_ACCOUNT);
public Account getAccount(long id) {
return jt.query(SELECT_ACCOUNT, EXTRACTOR_ACCOUNT, id);
}
我希望这有助于表明您现在可以非常轻松地以强大的方式组合各个部分,从而使您的域更简单。
更新 2:与可选值的可选值(而不是 null)结合使用。
public static <T> ResultSetExtractor<Optional<T>> singletonOptionalExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? Optional.of(mapper.mapRow(rs, 1)) : Optional.empty();
}
现在使用时可以具有以下特性:
private static final ResultSetExtractor<Optional<Double>> EXTRACTOR_DISCOUNT =
singletonOptionalExtractor(MAPPER_DISCOUNT);
public double getDiscount(long accountId) {
return jt.query(SELECT_DISCOUNT, EXTRACTOR_DISCOUNT, accountId)
.orElse(0.0);
}