SimpleJdbcTemplate: Spring 2.0 和 Java 5

工程 | Ben Hale | 2006年11月28日 | ...

Spring Experience 舉辦之前,我一直很忙,但我注意到 Rod 在部落格方面非常活躍。所以今天我在機場和飛機上的一些空閒時間裡,我決定寫一篇部落格。

我們在 Spring 社群中面臨的最大平衡之一是確保我們在保持向後相容性的同時,仍然進行創新。這種創新的一部分是利用 Java 5 等更高版本 Java 中的新特性和構造。自從 1.2.x 分支以來,我們已經看到了一些這樣的情況,例如 @Transactional 註解和基於 @ManagedResource 註解的 JMX 自動檢測。最終,這些都是很棒的功能,並且大大簡化了開發(至少對我來說是這樣),但它們實際上是將元資料移動到程式碼中。我們還沒有看到的是 API 的實際簡化。

隨著 Spring 2.0 的釋出,情況發生了變化。我們看到某些 API 利用了除註解之外的其他特性。事實上,有一個很好的例子,幾乎使用了 Java 5 的每個新語言特性(自動裝箱、可變引數、泛型),那就是 SimpleJdbcTemplateSimpleJdbcTemplate 並不是標準 JdbcTemplate 的完全替代品,而是使用 Java 5 來簡化某些常見任務。

自動裝箱

嚴格來說,自動裝箱並不是我們使用 API 做的事情,但它可以使 JdbcTemplate 的使用更加方便。例如,您以前必須對原始值進行裝箱...

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 查詢中,裝箱會佔用相當多的空間。

可變引數

如果我們看一下原始示例,我們會看到 Java 5 可以幫助我們刪除的另一段樣板程式碼。繫結引數作為 Object 陣列傳遞,但 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 = ?",
        value, type);
}

泛型

我們在 SimpleJdbcTemplate 中看到的最後一個改進是引入了泛型。當使用 JdbcTemplate 時,我最大的痛苦之一是,每當我使用 queryForObject() 時,我都必須進行手動型別轉換,並且沒有從我的 IDE 或編譯器那裡獲得太多幫助。

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 及更高版本中新特性的一個例子。

獲取 Spring 新聞通訊

與 Spring 新聞通訊保持聯絡

訂閱

更上一層樓

VMware 提供培訓和認證,以加速您的進步。

瞭解更多

獲得支援

Tanzu Spring 在一個簡單的訂閱中為 OpenJDK™、Spring 和 Apache Tomcat® 提供支援和二進位制檔案。

瞭解更多

即將舉行的活動

檢視 Spring 社群中所有即將舉行的活動。

檢視全部