คุณยังสามารถใช้ a 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
ได้ประโยชน์เพิ่มที่คุณสามารถจัดการกับทุกกรณีที่มีมากกว่าหนึ่งแถวหรือแถวไม่กลับ
UPDATE : หลายปีผ่านไปและฉันมีเทคนิคเล็กน้อยที่จะแบ่งปัน JdbcTemplate
ทำงานได้อย่างยอดเยี่ยมกับ java 8 lambdas ซึ่งตัวอย่างต่อไปนี้ออกแบบมาเพื่อ แต่คุณสามารถใช้คลาสแบบคงที่เพื่อให้ได้สิ่งเดียวกัน
แม้ว่าคำถามจะเกี่ยวกับประเภทง่ายๆ แต่ตัวอย่างเหล่านี้ใช้เป็นแนวทางสำหรับกรณีทั่วไปของการแยกออบเจ็กต์โดเมน
ก่อนอื่น 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 : รวมกับตัวเลือกสำหรับค่าทางเลือกแทนค่าว่าง
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
เป็นเครื่องมือที่มีประสิทธิภาพมากกว่าในกรณีนี้