당신은 또한 사용할 수 있습니다 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 람다와 훌륭하게 작동하지만 정적 클래스를 사용하여 동일한 결과를 얻을 수 있습니다.
질문은 단순 유형에 관한 것이지만이 예제는 도메인 객체를 추출하는 일반적인 경우에 대한 가이드 역할을합니다.
우선. 단순성을 위해 두 가지 속성이있는 계정 개체가 있다고 가정 해 보겠습니다 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
A는 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 대신 선택적 값에 대해 Optional 과 결합하십시오 .
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);
}
ResultSet.next()
불필요하게 호출된다는 것입니다.ResultSetExtractor
이 경우 a를 사용하는 것이 훨씬 더 효율적인 도구입니다.