web-dev-qa-db-ja.com

JdbcTemplate queryForInt / Longは、Spring 3.2.2で非推奨になりました。何に置き換える必要がありますか?

JdbcTemplateのqueryforInt/queryforLongメソッドは、Spring 3.2では非推奨です。これらの方法を使用して既存のコードを置き換えるためのベストプラクティスと考えられる理由や理由を見つけることはできません。

典型的な方法:

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

OK、上記のメソッドは次のように書き直す必要があります。

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

明らかに、この非推奨により、JdbcTemplateクラスがよりシンプルになります(またはそうしますか?)。 QueryForIntは常に便利なメソッドであり(私は推測します)、長い間使用されてきました。なぜ削除されたのですか。その結果、コードはより複雑になります。

100
Dan MacBean

私が思うのは、誰かがqueryForInt/Longメソッドが混乱したセマンティクスを持っていることに気づいたということです。つまり、JdbcTemplateソースコードから、現在の実装を見ることができます

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

結果セットが空の場合は0を返しますが、例外がスローされると考えるようになります。

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

したがって、次の実装は基本的に現在の実装と同等です。

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

そして、非推奨ではないコードは今やいものに置き換える必要があります:

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

またはこれ(より):

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

便利なメソッドqueryForLong(sql)を廃止することは不便であるという元のポスターに同意します。

Spring 3.1を使用してアプリを開発し、最新のSpringバージョン(3.2.3)に更新したところ、廃止されたことがわかりました。

幸いなことに、私にとっては1行の変更でした。

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

に変更されました

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

そして、いくつかの単体テストが示すように、上記の変更は機能します。

33
SGB

queryForObject(String, Class)を支持して廃止されました。

14
vertti

そのようなコードの置き換え:

long num = jdbcTemplate.queryForLong(sql);

このコードでは:

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

列がnull値を持つ場合、queryForObjectはnullを返し、プリミティブ型をnullにすることはできず、NullPointerExceptionが発生するため、非常に危険です。コンパイラはこれについて警告しませんでした。実行時にこのエラーについて知ることができます。プリミティブ型を返すメソッドがある場合、同じエラーが発生します。

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

Spring 3.2.2のJdbcTemplateの非推奨のメソッドqueryForLongの本文は次のとおりです。

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

プリミティブ値を返す前に、これがnullでないことを確認します。nullの場合、0を返します。ところで-0Lである必要があります。

13
Marcin Kapusta

JdbcTemplate#queryForIntは、列の値がSQL NULLまたは0の場合、0を返します。1つのケースを他のケースと区別する方法はありません。これがメソッドが非推奨になる主な理由だと思います。ところで、ResultSet#getIntは同様に動作します。ただし、ResultSet#wasNullによってこれら2つのケースを区別できます。

2
jddxf