posts - 176, comments - 240, trackbacks - 0, articles - 7

          [導入]SQL類:一件事一句話

          Posted on 2005-11-15 12:30 canonical 閱讀(274) 評論(0)  編輯  收藏 所屬分類: Witrix開發平臺

          在witrix平臺中訪問數據庫最直接的方法是使用edu.thu.db.SQL類。基本用法如下:
          //  設定數據庫連接參數, 連接可以通過java.sql.DriverManager 和

          //javax.sql.DataSource等多種方式建立,并支持數據庫連接緩沖池。
          TransactionMode db = new TransactionMode("default"); // 設定數據庫連接參數
          SQL sql = SQL.begin().select().field("id")
                               .from().table("other_table")
                .where().like("name","a%");
             .end();
          int n = SQL.begin().select().countAll()
                             .from().table("my_table")
                 .where().gt("value", new Integer(3)) // value > 3
                      .and().in("type", new String[]{"a","b"})  // type in ('a','b')
                   .and().in("data_id",sql)  // data_id in (select id from other_table where name like 'a%')
                .end().query(db).intValue();

          在SQL類的設計中體現了三個設計原則:
          1. 正交化的流式設計
          2. 參數對象化
          3. bug-free設計

          首先,SQL類將構造SQL語句,連接數據庫以及查詢結果類型轉換分解成了三個正交的部分。
          在一般的數據庫編程中,我們需要如下訪問方式:
          String sql = "select count(*) from my_table where value > ?";
          Connection conn = getConnection();
          PreparedStatement stmt = null;
          try{
               PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setParameter(1, valueLimit);
            ResultSet rs = stmt.executeQuery();
            rs.next();
            int ret = rs.getInt(1);
            // ...
          }finally{
           try{
            if(stmt != null)
             stmt.close();
           }catch(Exception e){
               e.printStackTrace();
           }

           try{
            conn.close();
           }catch(Exception e){
               e.printStackTrace();
           }
          }

          從 以上的例子中,我們可以注意到,在普通JDBC編程中,設置SQL語句的參數,建立數據庫連接,取得結果集中的結果并轉化為合適的格式這三者之間是交織在 一起的。特別是打開連接需要配對的關閉連接語句,造成整個程序的流程不是線性的, 因為我們不能說建立連接之后就可以不再管連接的事情了,我們必須記住在做完所有其他事情之后還要關閉連接。    通過一系列的封裝對象,SQL類實現了一種正交化的流式設計,其分解模式如下:
                SQL.begin().拼接SQL語句.end().建立連接并運行SQL語句.轉化結果()
          注意在SQL語句執行之后是不需要顯式關閉連接的。

          SQL類的第二個設計要點是參數對象化。在witrix平臺中,實際運行SQL語句的引擎函數是
           IDbEngine.execute(String sqlText, List sqlParameters, int resultType, int concurrency);
          這 里sqlText, sqlParameters等都是參數,但是在應用中構造這些參數的過程很復雜,并且非常靈活,一般的Util類(靜態Utility函數)無法提供有效 的簡化。 所以構造SQL語句這個過程不是通過util類完成的,而是通過一個專用的SqlBuilder對象。SQL的基本思想是將sql語句納入java程序框 架,使得sql語句成為程序中可控制的部分。首先SQL類將sql文本與sql參數封裝為一個完整的對象,使得sql語句的重用成為可能。其次, SqlBuilder類通過一種可控制的方式構造sql語句(所有的關鍵字都對應于一個函數),整個過程與直接書寫sql文本類似,但函數封裝使得我們能 夠在同一行上指定sql文本中用到的參數,而不是象jdbc里那樣,集中指定參數。同時SqlBuilder支持面向java語言的擴展,如直接支持 java集合類型等,從而大大簡化了sql語句的構造,因為一般sql拼接中最混亂的部分就是牽涉到循環與判斷。
            參數對象化的方法還可以應用于那些具有大量缺省參數的地方。在SQL類中,如果我們希望以scroll insensitive的方式選出數據,調用方式如下:
            SQL.begin().select().star()
                       .from().table("my_table")
             .end().scrollable(true).list(db,3,100);
          如果我們希望利用Statement.cancel()特性,我們可以指定cancelMonitor參數
             SQL.begin()....end().cancelMonitor(monitor).query(db).listValue();

          SQL 類的第三個設計要點是bug-free。jdbc中最常出現的錯誤是忘記關閉連接造成資源泄漏,在SQL類中,連接只在需要時才從緩沖池中獲取,當數據庫 操作完成(無論成功或失敗)時,數據庫連接會被自動關閉(或返回連接池),并自動處理提交和回滾的情況。整個程序代碼中一般沒有需要顯式關閉連接的要求, 從而極大的降低了資源泄漏的幾率,避免了這個錯誤的出現。這就如同java沒有要求程序員顯式釋放內存,從而在絕大多數情況下避免了memory leak的bug一樣。
          主站蜘蛛池模板: 廊坊市| 大理市| 溧水县| 正阳县| 建阳市| 喀喇沁旗| 奇台县| 绵阳市| 息烽县| 佛坪县| 滦平县| 芮城县| 司法| 刚察县| 永平县| 樟树市| 嘉义县| 类乌齐县| 黎川县| 太仆寺旗| 岗巴县| 神农架林区| 邵武市| 吐鲁番市| 五大连池市| 乌海市| 自治县| 密云县| 上栗县| 麻江县| 盈江县| 丰台区| 包头市| 定州市| 句容市| 卢湾区| 东宁县| 江都市| 呼伦贝尔市| 阿拉善左旗| 涞源县|