Spring JdbcTemplate源碼閱讀報告

  • 寫在前面

    spring一直以刪繁就簡爲主旨,因此設計出很是流行的bean管理模式,簡化了開發中的Bean的管理,少寫了不少重複代碼。而JdbcTemplate的設計更使人讚歎,輕量級,可作ORM也可如Jdbc般靈活。而在JdbcTemplate一個類中,蘊含了兩種設計模式,閱讀以後受益不淺,今日特此總結。mysql

  • 設計模式基礎

    若是硬讀,則走火入魔只得皮毛,幸得某篇博客的指點,先對設計模式進行熟悉,瞭解它的構造,再去閱讀,不只事半功倍還能增強理解。程序員

    jdbcTemplate中蘊含的兩個設計模式:流程控制模式、回調模式spring

    所謂流程控制,就是由父類定義一個方法,方法中蘊含多個流程,把固定的流程私有化,在其中調用,則子類沒法對私有化方法進行重寫;若將流程進行默認實現,則子類可選擇實現;若將流程抽象化,則推遲到子類去實現,也就是定製化實現,呈上代碼。sql

    譬如:煮牛肉,必須先切,醃(必要過程) 熱鍋放油(默認實現) 下鍋炒(定製過程)數據庫

public abstract class Father{
    //流程 m1->m2->m3
    public final void templateMethod(StatementCallback statementCallback){
        method1();
        method2();
        //抽象方法 子類負責實現 一般爲業務
        statementCallback.method3();//由接口提供
    }
    //父類私有方法 不能重寫 流程控制
    private void method1(){
        System.out.println("father private method, control by father ");
    }
    //鉤子方法 可實現 父類提供默認實現
    public void method2(){
        System.out.println("default method,prevent by father");
    }

}

    如上類,清晰的流程模型,基於method2定製化實現。這個設計模式有什麼好處呢?設計模式

    在咱們剛學習jdbc的時候,最多見的代碼,莫過於。數據結構

    String  driver="com.mysql.jdbc.Driver";  
    Connection con;  
    String url="jdbc:mysql://localhost:3306/demo";  
    String user="root";  
    String pwd="12345";  
    //鏈接上數據庫mysql  
    public void connection2MYSQL()  
    {  
        try {  
            Class.forName(driver);  
              
            con=DriverManager.getConnection(url,user,pwd);  
              
            if(!con.isClosed())  
                System.out.println("鏈接成功");  
      
        } catch (Exception e) {  
            e.printStackTrace();  
        }        
    }

    在反反覆覆的寫流程以後,設計者意識到這種無用功減慢效率,必須使用一種設計模式來讓程序員注意力更多得關注到更有價值的事情之上,因此這種固定流程,就歸入了流程中父類定義,而且不能修改的範圍內。異步

    第二種設計模式,回調模式。ide

    在現代互聯網隨處可見回調,這就是多態性的好處之一,只要須要,就能夠定製,諸如學習

$("#button").click(function(){
    //logic
});

    這種回調模式,在程序設計中大受歡迎,若是加上異步,則就是異步回調模型。它受歡迎的緣由,就是定製化。而Java中,構建回調模式只須要定義以下接口,並結合上述流程模式。

public interface StatementCallback {
    public void method3();
}

    所謂的定製,就是:等我須要的時候再叫你

public class Son extends Father{
    public void method3(){
        System.out.println("implement by son");
    }
}

public class Main {
    public static void main(String[] args){
        Father patten = new Son();
        patten.templateMethod(new StatementCallback() {
            @Override
            public void method3() {
                System.out.println("implement by user,callback");
            }
        });
    }
}

 

  • 源碼剖析

    它的各個方法最後都轉發到此方法來,此方法總體就是申請鏈接,執行sql,拿到結果,最後釋放鏈接,在紅色標註的地方就是定製化的體現。它封裝了不少個上層方法,好比queryForList,queryForMap,都是返回它封裝的數據結構。而最底層的流程就是上述方法。

    它提供默認實現的方式是匿名內部類。

    excute是爲了執行sql而設計的,而裏面的query方法和update則就是爲了讀寫分別設計的了。

    用過的人都知道,update返回int表示它操做的affects數目,而jdbc流行的一種返回主鍵的作法,就是在update中實現一個返回主鍵的邏輯,它用到的這個接口就是。

    下面代碼重寫了回調接口,使其返回插入的主鍵。

        int col = 0;
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(Connection con)
                    throws SQLException {
                PreparedStatement ps = con.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
                for(int i=0;i<args.length;i++){
                    ps.setObject(i+1,args[i]);
                }
                return ps;
            }
        }, keyHolder);
        col = keyHolder.getKey().intValue();

    其他接口未細讀,而對於jdbc來講,無非就是讀寫,咱們日常使用的是List和Map,它也能夠封裝Object,充當小型ORM,它以優秀的設計模式使得數據庫操做層的業務設計變得很是簡單清晰,而且它優秀的泛型處理技術,也是使人歎爲觀止。

相關文章
相關標籤/搜索