在Spring 3.2.2中不build议使用JdbcTemplate queryForInt / Long。 它应该被什么取代?
Spring 3.2中不推荐使用JdbcTemplate中的queryforInt / queryforLong方法。 我找不到为什么或什么被认为是使用这些方法取代现有代码的最佳实践。
一个典型的方法:
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总是一个方便的方法(我猜),已经有很长一段时间了。 为什么被删除。 代码变得越来越复杂。
我认为有人意识到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,但是它会抛出一个exception:
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); }
然后,现在的不被弃用的代码必须replace为丑陋的:
queryForObject(sql, new Object { arg1, arg2, ...}, Integer.class);
或者这个(更好):
queryForObject(sql, Integer.class, arg1, arg2, ...);
我同意原始的海报,反对便利方法queryForLong(sql)是一个不便。
我开发了一个使用Spring 3.1的应用程序,只是更新到最新的Spring版本(3.2.3),并注意到它已被弃用。
幸运的是,这对我来说是一个改变:
return jdbcTemplate.queryForLong(sql); // deprecated in Spring 3.2.x
被改为
return jdbcTemplate.queryForObject(sql, Long.class);
和几个unit testing似乎表明,上述改变的作品。
不推荐使用queryForObject(String, Class)
。
replace这样的代码:
long num = jdbcTemplate.queryForLong(sql);
有了这个代码:
long num = jdbcTemplate.queryForObject(sql, Long.class);
是非常危险的,因为如果列有空值queryForObject返回null,并且我们知道原始types不能为null,您将有NullPointerException。 编译器并没有警告你这个。 你会在运行时知道这个错误。 如果你有返回原始types的方法,你将会得到同样的错误:
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。
如果列值是SQL NULL或0, JdbcTemplate#queryForInt
将返回0。无法区分一种情况和另一种情况。 我认为这是该方法被弃用的主要原因。 顺便说一句, ResultSet#getInt
行为相似。 虽然,我们可以通过ResultSet#wasNull
来区分这两种情况。