領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多在 The Spring Experience 大會臨近之際,我一直很忙,但我注意到 Rod 在部落格方面非常活躍。所以今天在機場和飛機上的一些空閒時間裡,我決定寫一點部落格。
我們在 Spring 社群面臨的最大挑戰之一是既要保持向後相容,又要持續創新。創新的一部分是利用 Java 5 及更高版本的新特性和構造。自 1.2.x 分支以來,我們已經看到了一些這方面的例子,例如 `@Transactional` 註解以及基於 `@ManagedResource` 註解的 JMX 自動檢測。最終,這些都是很棒的特性,極大地簡化了開發(至少對我而言),但它們實際上是將元資料移到了程式碼中。我們還沒有看到 API 的實際簡化。
Spring 2.0 改變了這一點。我們看到某些 API 利用的不僅僅是註解。事實上,有一個很好的例子,其中幾乎所有 Java 5 的新語言特性(自動裝箱、可變引數、泛型)都被使用了,那就是 `SimpleJdbcTemplate`。`SimpleJdbcTemplate` 並不是標準 `JdbcTemplate` 的替代品,而是利用 Java 5 來簡化某些常見任務。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { new Double(value), new Integer(type) });
}
……現在你不再需要了。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { value, type });
}
在這個簡單的例子中,差異並不大,但你可以想象在一個具有多個繫結變數的複雜 SQL 查詢中,裝箱會佔用相當大的空間。
所以,如果我們從最初的例子開始……
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
new Object[] { new Double(value), new Integer(type) });
}
……結合自動裝箱和可變引數,程式碼真的開始變短了。
public int getLargeAccountCount(double value, int type) {
return getSimpleJdbcTemplate().queryForInt(
"select count(*) from accounts where balance > ? and type = ?",
value, type);
}
public Account getAccount(long id) {
return (Account) getJdbcTemplate().queryForObject(
"select * from accounts where id = ?",
new Object[] { new Long(id) }, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum)
throws SQLException {
String accountNumber = rs.getString("account_number");
int balance = rs.getInt("balance");
return new Account(accountNumber, balance);
}
});
}
在 Spring 2.0 中,我們釋出了 `SimpleJdbcTemplate` 的伴侶 `ParameterizedRowMapper`。當兩者一起使用時,它們實際上建立了一個非常漂亮的系統,完全不需要型別轉換,並且你的 IDE 和編譯器會進行強型別檢查。
public Account getAccount(long id) {
return getSimpleJdbcTemplate().queryForObject(
"select * from accounts where id = ?",
new ParameterizedRowMapper<Account>() {
public Account mapRow(ResultSet rs, int rowNum)
throws SQLException {
String accountNumber = rs.getString("account_number");
int balance = rs.getInt("balance");
return new Account(accountNumber, balance);
}
}, id);
}
有一點很重要,那就是 `SimpleJdbcTemplate` 並沒有包含 `JdbcTemplate` 的所有方法。它甚至不繼承 `JdbcTemplate`,而是可以提供一個 `JdbcTemplate` 的引用。`SimpleJdbcTemplate` 的目標是在利用 Java 5 的同時,簡化一些常見行為的使用。
總而言之,這並不是什麼革命性的東西。就像 Rod 在他早期的帖子中提到的那樣,這只是語法糖。但這是 Spring 擁抱 Java 5 及以後新特性的一個例子。