Anda juga dapat menggunakan a, ResultSetExtractor
bukan RowMapper
. Keduanya semudah satu sama lain, satu-satunya perbedaan adalah Anda menelepon 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;
}
});
}
The ResultSetExtractor
memiliki manfaat tambahan bahwa Anda dapat menangani semua kasus di mana ada lebih dari satu baris atau tidak ada baris yang dikembalikan.
PEMBARUAN : Beberapa tahun berlalu dan saya memiliki beberapa trik untuk dibagikan. JdbcTemplate
bekerja luar biasa dengan java 8 lambda yang dirancang untuk contoh berikut tetapi Anda dapat dengan mudah menggunakan kelas statis untuk mencapai hal yang sama.
Sementara pertanyaannya adalah tentang tipe sederhana, contoh ini berfungsi sebagai panduan untuk kasus umum penggalian objek domain.
Pertama. Misalkan Anda memiliki objek akun dengan dua properti untuk kesederhanaan Account(Long id, String name)
. Anda mungkin ingin memiliki RowMapper
untuk objek domain ini.
private static final RowMapper<Account> MAPPER_ACCOUNT =
(rs, i) -> new Account(rs.getLong("ID"),
rs.getString("NAME"));
Sekarang Anda dapat menggunakan mapper ini secara langsung di dalam metode untuk memetakan Account
objek domain dari kueri ( jt
adalah sebuah JdbcTemplate
instance).
public List<Account> getAccounts() {
return jt.query(SELECT_ACCOUNT, MAPPER_ACCOUNT);
}
Bagus, tapi sekarang kami menginginkan masalah asli kami dan kami menggunakan solusi asli saya menggunakan kembali RowMapper
untuk melakukan pemetaan untuk kami.
public Account getAccount(long id) {
return jt.query(
SELECT_ACCOUNT,
rs -> rs.next() ? MAPPER_ACCOUNT.mapRow(rs, 1) : null,
id);
}
Bagus, tetapi ini adalah pola yang mungkin dan ingin Anda ulangi. Jadi, Anda dapat membuat metode pabrik umum untuk membuat yang baru ResultSetExtractor
untuk tugas tersebut.
public static <T> ResultSetExtractor singletonExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? mapper.mapRow(rs, 1) : null;
}
Membuat ResultSetExtractor
sekarang menjadi hal yang sepele.
private static final ResultSetExtractor<Account> EXTRACTOR_ACCOUNT =
singletonExtractor(MAPPER_ACCOUNT);
public Account getAccount(long id) {
return jt.query(SELECT_ACCOUNT, EXTRACTOR_ACCOUNT, id);
}
Saya harap ini membantu untuk menunjukkan bahwa Anda sekarang dapat dengan mudah menggabungkan bagian-bagian dengan cara yang ampuh untuk membuat domain Anda lebih sederhana.
UPDATE 2 : Gabungkan dengan Opsional untuk nilai opsional, bukan null.
public static <T> ResultSetExtractor<Optional<T>> singletonOptionalExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? Optional.of(mapper.mapRow(rs, 1)) : Optional.empty();
}
Yang sekarang bila digunakan bisa memiliki yang berikut:
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()
akan dipanggil jika tidak perlu. Dalam kasus ini, menggunakan alatResultSetExtractor
yang jauh lebih efisien.