SimpleJdbcTemplate:Spring 2.0 和 Java 5

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

The Spring Experience的籌備期間,我一直很忙,但我注意到 Rod 在部落格方面非常活躍。所以在機場和飛機上的一些空閒時間,我決定寫一篇部落格。

我們 Spring 社群中最大的平衡工作之一,就是確保我們在創新的同時,保持向後相容。 這種創新的一部分是利用 Java 後續版本(例如 Java 5)中的新功能和結構。 自 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 社群中所有即將到來的活動。

查看全部