2013-03-27 130 views
89

Spring 3.2中不贊成使用JdbcTemplate中的queryforInt/queryforLong方法。我找不到爲什麼或被認爲是使用這些方法替換現有代碼的最佳實踐。JdbcTemplate queryForInt/Long在Spring 3.2.2中不推薦使用。它應該取代什麼?

的典型方法:

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

確定上述方法需要重新編寫如下:(?或者它)

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總是一個方便的方法(我猜),並且已經存在很長時間了。爲什麼它被刪除。代碼因此變得更加複雜。

+0

這方面的細節不贊成的方法:http://static.springsource.org/spring/docs/current/javadoc-api/deprecated-list.html – 2013-03-27 14:28:32

+0

你說得對,我不知道爲什麼我的源沒有@ @ Deprecated' – 2013-03-27 14:30:23

+0

將Spring版本更新到3.2.2 - 因爲它似乎在這裏首先被棄用 – 2013-03-27 14:30:46

回答

91

我覺得是有人意識到,queryForInt /長方法有混亂的語義,即從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, ...); 
+12

這是不正確的。第三個代碼片段不等於實現!因爲有一個隱藏的NPE與自動拆箱。如果您的查詢返回結果,但它們爲空,則以前的代碼將返回0而不是null - 爲了正確地重現以前的行爲,它將是: Integer result = queryForObject(sql,args,Integer.class); 返回結果== null? 0:結果; – MetroidFan2002 2013-12-05 18:26:34

+0

@ MetroidFan2002:的確你的觀察是真的!然而,從API設計的角度來看,如果查詢只返回一個NULL值,我認爲最好按原樣返回它,而不是asumming(as queryForInt do),NULL等於0.這是作業的API用戶評估這種情況。 – 2013-12-06 14:31:18

+0

問題是,如果用戶在那裏得到一個NPE,除非他們明確地在他們的環境中設置了某些東西(例如,Eclipse可以選擇突出顯示自動裝箱的用法),那麼該線上的NPE看起來就像JDBCOperations實例爲null。以前,零將被返回。現在爲什麼你會在一個返回null的查詢中使用它,我不知道(這基本上是由於n00bs這樣做,他們會這樣做),但是把它們拿走並不是一個很好的舉動IMO。 – MetroidFan2002 2013-12-06 16:20:12

14

不推薦使用queryForObject(String, Class)

32

我同意樓主說棄用方便的方法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); 

和幾個單元測試的似乎表明,上述變化的作品。

+0

好點。如果沒有括號,它也可以正常工作。 :) – SGB 2015-04-04 13:30:22

11

更換這樣的代碼:

long num = jdbcTemplate.queryForLong(sql); 

有了這個代碼:

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

是非常危險的,因爲如果有列空值queryForObject返回null,因爲我們知道原始的類型不能爲空,你將會有NullPointerException。編譯器並未警告您這一點。你會在運行時知道這個錯誤。

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

在Spring中的方法已過時queryForLong中的JdbcTemplate 3.2.2有以下身體:

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

你看他們回來之前同樣的錯誤,如果你有方法返回原始類型,你將有原始值有檢查,這不是null,如果它爲null,它們返回0.順便說一句 - 應該是0L。

+3

2美分:如果啓用了自動裝箱警告,編譯器可能會警告您。 – keiki 2014-04-22 07:20:12

+0

我不知道這件事。感謝隊友:) – 2014-04-24 07:39:26

1

JdbcTemplate#queryForInt如果列值爲SQL NULL或0,則返回0。無法區分一種情況與另一種情況。我認爲這是該方法不推薦使用的主要原因。順便說一句,ResultSet#getInt行爲相似。雖然,我們可以通過ResultSet#wasNull來區分這兩種情況。

-1
public int getCircleCount() { 
    Object param = "1"; 
    String sql = "select count(*) from circle where id = ? "; 
    jdbcTemplate.setDataSource(getDataSource()); 
    int result = getJdbcTemplate().queryForObject(sql, new Object[] { param }, Integer.class); 
    return result; 
} 
+0

請解釋你的答案。 – 2018-03-05 06:56:00

相關問題