Ви також можете використовувати 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це 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);
}
ResultSet.next()були б викликані без потреби. Використання aResultSetExtractorє набагато ефективнішим інструментом у цьому випадку.