nighty

          折騰的年華
          posts - 37, comments - 143, trackbacks - 0, articles - 0

          關于commons dbutils組件的一個小缺陷分析

          Posted on 2011-02-12 17:33 寒武紀 閱讀(3031) 評論(7)  編輯  收藏 所屬分類: 數據庫Java
                  非常喜歡這種輕量級的JDBC封裝,比起Hibernate和iBatis,可以非常自由和靈活地運用和自行二次封裝,由于dbutils的BeanHandler轉換方式采取了反射技術,在性能上肯定有所損失,所以項目中基本上都使用MapHandler方式來轉換數據,當然就是自己寫的代碼多一點,也無所謂。一般的查詢、子查詢、聯合查詢、包括視圖查詢等等都很正常,但是發現一個比較小的問題,就是在使用聚合函數的場所,例如:select user_type, count(*) as count from `user` group by user_type這種類型查詢的時候,MapHandler方式不起作用,as列都變成key為空串的K-V對,導致有許多地方使用map.get("")代碼的情況出現,這種寫法當然是不太好的,容易出問題。
                  鑒于前面沒有時間了解,就都粗略使用了上面那種粗暴的map.get("")來處理,最好的情況是讓dbutils組件能自動識別到as類型的列名。于是有空了就專門看了看它的源代碼,發現最主要的一段代碼如下:
           1public Map<String, Object> toMap(ResultSet rs) throws SQLException {
           2        Map<String, Object> result = new CaseInsensitiveHashMap();
           3        ResultSetMetaData rsmd = rs.getMetaData();
           4        int cols = rsmd.getColumnCount();
           5
           6        for (int i = 1; i <= cols; i++{
           7            result.put(rsmd.getColumnName(i), rs.getObject(i));
           8        }

           9
          10        return result;
          11    }
                  CaseInsensitiveHashMap是dbutils自定義的一個Map,忽略鍵大小寫的K-V字典,但是key使用的是ResultSetMetaData.getColumnName(),我想問題大概出在這里,于是認真翻了翻java的api文檔(開發做久了容易遺忘基礎),果然,原來getColumnName()是:獲取指定列的名稱;而as關鍵字之后,使列名稱變成用于顯示的意義,這個時候應該使用getColumnLabel():獲取用于打印輸出和顯示的指定列的建議標題。建議標題通常由 SQL AS 子句來指定。如果未指定 SQL AS,則從 getColumnLabel 返回的值將和 getColumnName 方法返回的值相同。自己手動試驗了一下,果然如所料,問題就出在這里。
                  所以呢,如果想要dbutils在自動轉換Map及MapList時能識別聚合函數的列名,那么最好的做法就是重載這種方式,懶一點的,你就干脆修改上面那段代碼,讓它判斷是否使用了as關鍵字。個人暫時搞不清楚官方為什么沒有考慮這一步,有時間再思考一下!

          剛進場的時候戲就落幕

          Feedback

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-12 20:22 by 蒙奇奇
          關注

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-13 19:30 by javafan
          本來就是一個Bug,無法識別別名,低版本沒問題

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-14 13:56 by retry
          什么版本? 是 1.3 么?

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-14 18:08 by 寒武紀
          @retry
          是的,就是1.3

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-19 12:21 by jacklondon
          我也用 dbutils 進行二次封裝成 VelocityWeb, 也用 as , 沒有發現這個 bug。 可能是因為我攔截了 map , 因為我的需求比較特別:
          user_name (數據庫列名) 要映射到 userName( java 屬性名), 而 DBUtils 做不到,所以我攔截了重寫,可能是因為這樣,導致沒有了這個 bug.
          ----------歡迎大家試用我們的單點登錄 http://zhegui.biz

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2011-02-19 12:25 by jacklondon
          DBUtils 1.3 的 release log 中有如下一段話,按說已經解決問題了:
          BeanProcessor#mapColumnsToProperties now prefers to use column labels over column names (where aliases are not set, these should be identical) Fixes DBUTILS-57.

          你這邊用什么數據庫?是否 JDBC 驅動有問題,需要升級?

          # re: 關于commons dbutils組件的一個小缺陷分析  回復  更多評論   

          2016-05-02 20:35 by starhe
          dbutils中連傳入到的參數都不區分大小寫??
          主站蜘蛛池模板: 英山县| 木兰县| 阿荣旗| 图木舒克市| 灵山县| 子洲县| 虞城县| 金坛市| 东源县| 龙游县| 五峰| 普安县| 麟游县| 京山县| 元朗区| 大姚县| 泰宁县| 镇巴县| 万载县| 曲麻莱县| 社旗县| 白水县| 五峰| 肇源县| 来宾市| 黔东| 综艺| 姜堰市| 海宁市| 绍兴市| 宁化县| 巴彦县| 晋州市| 泊头市| 永宁县| 那曲县| 邹平县| 辽阳市| 临夏县| 绵竹市| 静安区|