1. 程式人生 > 其它 >jdbctemplate連線釋放_設計模式及其在Spring中的應用——模板模式 在JdbcTemplate中...

jdbctemplate連線釋放_設計模式及其在Spring中的應用——模板模式 在JdbcTemplate中...

技術標籤:jdbctemplate連線釋放

模板模式JdbcTemplate

模板模式

4c8d1c4580cf70b548df0e3e3bc72f39.png
模板模式UML圖

在模板模式中:

父類定義了骨架(呼叫哪些方法及順序),某些特定方法由子類實現。

最大的好處:程式碼複用,減少重複程式碼。除了子類要實現的特定方法,其他方法及方法呼叫順序都在父類中預先寫好了。

所以父類模板方法中有兩類方法:

共同的方法: 所有子類都會用到的程式碼

不同的方法: 子類要覆蓋的方法,分為兩種:

  • 抽象方法:父類中的是抽象方法,子類必須覆蓋
  • 鉤子方法:父類中是一個空方法,子類繼承了預設也是空的

注:為什麼叫鉤子方法?子類可以通過這個鉤子(方法),控制父類,因為這個鉤子實際是父類的方法(空方法)!


JdbcTemplate實現原理:

定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。 Template Method模式一般是需要繼承的。這裡想要探討另一種對Template Method的理解。spring中的JdbcTemplate,在用這個類時並不想去繼承這個類,因為這個類的方法太多,但是我們還是想用到JdbcTemplate已有的穩定的、公用的資料庫連線,那麼我們怎麼辦呢?我們可以把變化的東西抽出來作為一個引數傳入JdbcTemplate的方法中。但是變化的東西是一段程式碼,而且這段程式碼會用到JdbcTemplate中的變數。怎麼辦?那我們就用回撥物件吧。在這個回撥物件中定義一個操縱JdbcTemplate中變數的方法,我們去實現這個方法,就把變化的東西集中到這裡了。然後我們再傳入這個回撥物件到JdbcTemplate,從而完成了呼叫。這可能是Template Method不需要繼承的另一種實現方式吧。

  • jdbctemplate如何呼叫executor():

JDBC的抽象和對Hibernate的整合,都採用了一種理念或者處理方式,那就是模板方法模式與相應的Callback介面相結合。

採用模板方法模式是為了以一種統一而集中的方式來處理資源的獲取和釋放,以JdbcTempalte為例:

 publicabstractclass JdbcTemplate {
      publicfinal Object execute(String sql){
         Connection con=null;
         Statement stmt=null;
         try{
             con=getConnection();
             stmt=con.createStatement();
             Object retValue=executeWithStatement(stmt,sql);
             return retValue;
         }catch(SQLException e){
              ...
         }finally{
             closeStatement(stmt);
             releaseConnection(con);
         }
     }
     protectedabstract Object executeWithStatement(Statement   stmt, String sql);
 }
  • 引入回撥原因:

JdbcTemplate是抽象類,不能夠獨立使用,我們每次進行資料訪問的時候都要給出一個相應的子類實現,這樣肯定不方便,所以就引入了回撥。

回撥程式碼

 publicinterface StatementCallback{
     Object doWithStatement(Statement stmt);
 }

利用回撥方法重寫JdbcTemplate方法

 publicclass JdbcTemplate {
     publicfinal Object execute(StatementCallback callback){
         Connection con=null;
         Statement stmt=null;
         try{
             con=getConnection();
             stmt=con.createStatement();
             Object retValue=callback.doWithStatement(stmt);
             return retValue;
         }catch(SQLException e){
             ...
         }finally{
             closeStatement(stmt);
             releaseConnection(con);
         }
     }
 ​
     ...//其它方法定義
 }

Jdbc使用方法如下:

 JdbcTemplate jdbcTemplate=...;
     final String sql=...;
     StatementCallback callback=new StatementCallback(){
     public Object=doWithStatement(Statement stmt){
         return ...;
     }
 }
 jdbcTemplate.execute(callback);
  • 為什麼JdbcTemplate沒有使用繼承?

因為這個類的方法太多,但是我們還是想用到JdbcTemplate已有的穩定的、公用的資料庫連線,那麼我們怎麼辦呢?

我們可以把變化的東西抽出來作為一個引數傳入JdbcTemplate的方法中。但是變化的東西是一段程式碼,而且這段程式碼會用到JdbcTemplate中的變數。怎麼辦?

那我們就用回撥物件吧。在這個回撥物件中定義一個操縱JdbcTemplate中變數的方法,我們去實現這個方法,就把變化的東西集中到這裡了。然後我們再傳入這個回撥物件到JdbcTemplate,從而完成了呼叫。

總章連結

Cloudistory:設計模式及其在Spring中的應用​zhuanlan.zhihu.com zhihu-card-default.svg