web-dev-qa-db-fra.com

JdbcTemplate queryForInt / Long est obsolète en Spring 3.2.2. Par quoi devrait-il être remplacé?

Les méthodes queryforInt/queryforLong dans JdbcTemplate sont obsolètes dans Spring 3.2. Je ne peux pas savoir pourquoi ni ce qui est considéré comme la meilleure pratique pour remplacer le code existant en utilisant ces méthodes.

Une méthode typique:

int rowCount = jscoreJdbcTemplate.queryForInt(
    "SELECT count(*) FROM _player WHERE nameKey = ? AND teamClub = ?",
    playerNameKey.toUpperCase(),
    teamNameKey.toUpperCase()
);

OK, la méthode ci-dessus doit être réécrite comme suit:

Object[] params = new Object[] { 
   playerNameKey.toUpperCase(), 
   teamNameKey.toUpperCase()
};
int rowCount = jscoreJdbcTemplate.queryForObject(
    "SELECT count(*) FROM _player WHERE nameKey = ? AND teamClub = ?",
    params, Integer.class);

Évidemment, cette dépréciation rend la classe JdbcTemplate plus simple (ou le fait-il?). QueryForInt a toujours été une méthode pratique (je suppose) et existe depuis longtemps. Pourquoi a-t-il été supprimé? Le code devient alors plus compliqué.

100
Dan MacBean

Ce que je pense, c'est que quelqu'un s'est rendu compte que les méthodes queryForInt/Long ont une sémantique déroutante, c'est-à-dire qu'à partir du code source de JdbcTemplate, vous pouvez voir son implémentation actuelle:

@Deprecated
public int queryForInt(String sql, Object... args) throws DataAccessException {
    Number number = queryForObject(sql, args, Integer.class);
    return (number != null ? number.intValue() : 0);
}

ce qui peut vous amener à penser que si le jeu de résultats est vide, il retournera 0, mais il lève une exception:

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

de sorte que l'implémentation suivante est essentiellement équivalente à l'actuelle:

@Deprecated
public int queryForInt(String sql, Object... args) throws DataAccessException {
    return queryForObject(sql, args, Integer.class);
}

Et puis le code non obsolète doit maintenant être remplacé par le laid:

    queryForObject(sql, new Object { arg1, arg2, ...}, Integer.class);

ou ceci (plus gentil):

    queryForObject(sql, Integer.class, arg1, arg2, ...);
107

Je suis d'accord avec l'affiche originale qui déprécie la méthode de commodité queryForLong (sql) est un inconvénient.

J'avais développé une application utilisant Spring 3.1 et venais de mettre à jour la dernière version de Spring (3.2.3) et j'avais remarqué qu'elle était obsolète.

Heureusement, ce fut un changement d'une ligne pour moi:

return jdbcTemplate.queryForLong(sql);  // deprecated in Spring 3.2.x

a été changé en

return jdbcTemplate.queryForObject(sql, Long.class);

Et quelques tests unitaires semblent indiquer que le changement ci-dessus fonctionne.

33
SGB

Déconseillé en faveur de queryForObject(String, Class).

14
vertti

Remplacement de ce code:

long num = jdbcTemplate.queryForLong(sql);

Avec ce code:

long num = jdbcTemplate.queryForObject(sql, Long.class);

est très dangereux parce que si la colonne a une valeur nulle, queryForObject renvoie null et, comme nous le savons, les types primitifs ne peuvent pas être nuls et vous aurez NullPointerException. Le compilateur ne vous a pas averti à ce sujet. Vous saurez à propos de cette erreur au moment de l'exécution. La même erreur que vous aurez si vous avez une méthode qui retourne un type primitif:

public long getValue(String sql) {
    return = jdbcTemplate.queryForObject(sql, Long.class);
}

La méthode obsolète queryForLong dans JdbcTemplate dans Spring 3.2.2 a le corps suivant:

@Deprecated
public long queryForLong(String sql) throws DataAccessException {
    Number number = queryForObject(sql, Long.class);
    return (number != null ? number.longValue() : 0);
}

Vous voyez qu'avant de renvoyer une valeur primitive, il est vérifié que cela n'est pas null et si c'est null, ils renvoient 0. Soit dit en passant - Doit être 0L.

13
Marcin Kapusta

JdbcTemplate#queryForInt renvoie 0 si la valeur de la colonne est SQL NULL ou 0. Il n'y a aucun moyen de distinguer un cas de l'autre. Je pense que c'est la raison principale pour laquelle cette méthode est déconseillée. BTW, ResultSet#getInt se comporte de la même manière. Cependant, on peut distinguer ces deux cas par ResultSet#wasNull.

2
jddxf