1. 程式人生 > >由SpringJdbc引發的一點思考

由SpringJdbc引發的一點思考

本來專案中使用的是Hibernate,後來換Mybatis,但由於專案中很多sql語句是動態的,無實體,引數不固定,列也不固定,Mybatis顯得太重量了,所以我又選擇用spring jdbc這種更輕量的封轉替換掉原來的jdbc,更換dao層真心讓我想吐了。


其實,無論Spring jdbc,Hibernate,還是mybatis都是對jdbc的封裝,封裝不變的部分,留下可變的部分讓我們自己寫。

使用 Spring jdbc,其實最主要的是使用它的三個模板,Spring的JdbcTemplate、NamedParameterJdbcTemplate和SimpleJdbcTemplate。我們從Spring 的JdbcTemplate開始說,這是其他模板的基礎,NamedParameterJdbcTemplate和SimpleJdbcTemplate 都是在 JdbcTemplate的基礎之上封裝的。


1、JdbcTemplate

執行過程:定義SQL,其次呼叫JdbcTemplate方法執行SQL,並傳遞引數,最後通過RowCallbackHandler回撥處理ResultSet結果集。另外,JdbcTemplate類對可變部分採用回撥介面方式實現,如ConnectionCallback通過回撥介面返回給使用者一個連線,從而可以使用該連 接做任何事情、StatementCallback通過回撥介面返回給使用者一個Statement,從而可以使用該Statement做任何事情。當然還有其他介面,不再贅述。

2、NamedParameterJdbcTemplate

NamedParameterJdbcTemplate類是基於JdbcTemplate類,並對它進行了封裝從而支援命名引數特性。

什麼是命名引數特性?

PreparedStatement p = con.prepareStatement("select * from people where (first_name = ? or last_name = ?) and address = ?");
p.setString(1, name);
p.setString(2, name);
p.setString(3, address);

這種問好的形式,引數是匿名並被通過索引設定,靈活性太差,而且引數多的時候,非常容易出錯,可讀性非常差。

String query = "select * from people where (first_name = :name or last_name = :name) and address = :address");
NamedParameterStatement p = new NamedParameterStatement(con, query);
p.setString("name", name);
p.setString("address", address);

以上這種形式,就成為命名引數形式,從程式碼靈活性,可讀性和效能上和前者差不多。

NamedParameterJdbcTemplate 就是這種命名引數的一種實現。

3、SimpleJdbcTemplate

SimpleJdbcTemplate類也是基於JdbcTemplate類,但利用Java5+的可變引數列表和自動裝箱和拆箱從而獲取更簡潔的程式碼。

SimpleJdbcTemplate主要提供兩類方法:query及queryForXXX方法、update及batchUpdate方法。SimpleJdbcTemplate類還支援命名引數特性,如 queryForList(String sql, SqlParameterSource args)和queryForList(String sql, Map<String, ?> args) ,類似於NamedParameterJdbcTemplate中使用,在此就不介紹了。

SimpleJdbcTemplate,從名字上看,它是進一步簡化jdbc操作,把我們常用的方式封裝起來。

但從Spring 3.1開始,JdbcTemplate和NamedParameterJdbcTemplate提供了SimpleJdbcTemplate的功能,SimpleJdbcDaoSupport被標記為

原始碼中,有說明:

@deprecated since Spring 3.1 in favor of {@link org.springframework.jdbc.core.JdbcTemplate} and

 {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}. The JdbcTemplate and  NamedParameterJdbcTemplate now provide all the functionality of the SimpleJdbcTemplate.

總結:

之所以會寫這篇文章,是因為在dao層的選型上走了不少彎路,因為專案中沒有實體類,我放棄了Hibernate,選用mybatis,後來因為mybatis的mapper檔案,我又棄之,選擇spring jdbctemplate,一度因為其不支援命名引數,我自己實現了一個 NamedParameterStatement ,後來發現,springjdbc中的NamedParameterJdbcTemplate已經實現了這個功能,而且比我實現的要好不少,果斷放棄我自己寫的,改用這個,走了不少彎路,發現自己全域性觀還是有些問題的,做事情前的思考不夠充分,總是想趕緊做出東西來,一頭扎進去,做不動了才開始思考,導致多次返工,血與淚的教訓啊。