Vous pouvez également utiliser un ResultSetExtractor
au lieu d'un RowMapper
. Les deux sont aussi simples l'un que l'autre, la seule différence est que vous appelez 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;
}
});
}
Le ResultSetExtractor
a l'avantage supplémentaire que vous pouvez gérer tous les cas où il y a plus d'une ligne ou aucune ligne renvoyée.
MISE À JOUR : Plusieurs années plus tard et j'ai quelques astuces à partager. JdbcTemplate
fonctionne parfaitement avec java 8 lambdas pour lesquels les exemples suivants sont conçus, mais vous pouvez assez facilement utiliser une classe statique pour obtenir la même chose.
Bien que la question porte sur les types simples, ces exemples servent de guide pour le cas courant de l'extraction d'objets de domaine.
Tout d'abord. Supposons que vous ayez un objet compte avec deux propriétés pour plus de simplicité Account(Long id, String name)
. Vous souhaiteriez probablement avoir un RowMapper
objet pour ce domaine.
private static final RowMapper<Account> MAPPER_ACCOUNT =
(rs, i) -> new Account(rs.getLong("ID"),
rs.getString("NAME"));
Vous pouvez maintenant utiliser ce mappeur directement dans une méthode pour mapper des Account
objets de domaine à partir d'une requête ( jt
est une JdbcTemplate
instance).
public List<Account> getAccounts() {
return jt.query(SELECT_ACCOUNT, MAPPER_ACCOUNT);
}
Excellent, mais maintenant nous voulons notre problème d'origine et nous utilisons ma solution originale en réutilisant le RowMapper
pour effectuer le mappage pour nous.
public Account getAccount(long id) {
return jt.query(
SELECT_ACCOUNT,
rs -> rs.next() ? MAPPER_ACCOUNT.mapRow(rs, 1) : null,
id);
}
Génial, mais c'est un modèle que vous pouvez et voudrez répéter. Vous pouvez donc créer une méthode de fabrique générique pour en créer une nouvelle ResultSetExtractor
pour la tâche.
public static <T> ResultSetExtractor singletonExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? mapper.mapRow(rs, 1) : null;
}
Créer un ResultSetExtractor
maintenant devient trivial.
private static final ResultSetExtractor<Account> EXTRACTOR_ACCOUNT =
singletonExtractor(MAPPER_ACCOUNT);
public Account getAccount(long id) {
return jt.query(SELECT_ACCOUNT, EXTRACTOR_ACCOUNT, id);
}
J'espère que cela aidera à montrer que vous pouvez désormais combiner assez facilement des parties de manière puissante pour simplifier votre domaine.
MISE À JOUR 2 : À combiner avec une option facultative pour les valeurs facultatives au lieu de null.
public static <T> ResultSetExtractor<Optional<T>> singletonOptionalExtractor(
RowMapper<? extends T> mapper) {
return rs -> rs.next() ? Optional.of(mapper.mapRow(rs, 1)) : Optional.empty();
}
Qui maintenant, lorsqu'il est utilisé, pourrait avoir les éléments suivants:
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()
appelé inutilement. L'utilisation d'unResultSetExtractor
est un outil beaucoup plus efficace dans ce cas.