iBATIS with MapBean應用淺析
用了兩年的Hibernate之后,對ORM深有感觸。一方面,ORM可以令到我們從OO角度來思考數據,屏蔽了數據庫的差異(其實Hibernate被吹的最厲害就是那個分頁,其實分頁沒什么技術含量,而且ROR都把分頁從核心抽離了)。另一方面,性能問題,例如必須select才能update,必須select全部,必須update全部,cache帶來的后遺癥,JavaBean關聯問題(一對多,多對一,多對多等),lazyload問題。當然,小型項目是很有優勢的
Hibernate一直說,他生成的sql比一般程序員的要好,可以減少很多問題。但是,我倒是認為用Hibernate反而因為對程序員的要求更高導致更多問題。而且我現在認為,SQL才是王道,至少目前是。
于是在新項目中啟用iBATIS,這一年來的使用感覺很不錯,全程使用細粒度的SQL語句,雖然多寫了很多SQL語句,但是感覺到項目在自己的控制中
我只用了iBATIS 40%不到的功能,可能大家會覺得不可思議。我沒有用cache,沒有用關聯,沒有用resultMap,甚至,連JavaBean也沒有用
在大家都在討論PO,VO,DTO的時候,我的系統里面一個JavaBean都沒有
首先我問問,JavaBean是用來做什么的,存儲數據,每一個PO,其實就約等于一個表里面的一行數據
我舉一個真實一點的例子,一個user表
- public class User {
- private int id;
- private String name;
- // 省略getter/setter一大段
- }
不知道大家有沒有用eclipse生成JavaBean getter/setter的痛苦,至少非常枯燥。整個JavaBean實現了什么功能?完全沒有
好了我開謎底了,我用的是HashMap
什么,HashMap?是不是聽錯了
沒聽錯,請問有什么事情是上面那個那么普通的JavaBean能做到的,而HashMap不能做到的呢
用HashMap沒有具體屬性的類型啊,那不是變成動態語言一樣了,而且我要在JavaBean里面加邏輯怎么辦
好吧,這是我想到的兩個問題(如果你也有別的問題可以留意提出來)
首先,現在不同以前了,動態語言的優勢慢慢提高了,像動態語言有什么不好,我從ROR里面學了很多不錯的思想
其次是要加邏輯怎么辦,這個問題,之前在Javaeye討論充血模型還是貧血模型不可開交,***還是沒什么結論,目前還是一片貧血的情況,你可以翻一下你的項目里面的JavaBean,至少大多數的Bean都是沒有意義的getter/setter。BO跟PO混雜在一起也很多人不建議的。至于邏輯,大可以寫在util包里面,我都把整個model包去掉了,強化一下util不成么,呵呵
再次,數據庫的列,跟JavaBean的屬性兩者,本來就是冗余的,如果我們修改數據庫結構,就還要修改相應的JavaBean,或者影射文件。當然我這種做法更依賴數據庫。另外,ROR的名字轉換功能可以令到代碼中的調用名字更好看一些,我覺得也不是非常有必要的實現
直接使用HashMap不太方便,尤其是類型轉換上,于是我實現了一個MapBean的類,其實這個類很簡單,關鍵是用HashMap代替JavaBean的思想
- public class MapBean extends HashMap﹤String, Object﹥ {
- public MapBean() {
- }
- public MapBean(Object... args) {
- put(args);
- }
- public int getInt(Object key) {
- return getInt(key, 0);
- }
- public int getInt(Object key, int defaultInt) {
- Integer i = (Integer) get(key);
- return i == null ? defaultInt : i;
- }
- public String getString(Object key) {
- return (String) get(key);
- }
- public String getString(Object key, String defaultValue) {
- String value = (String) get(key);
- return value == null ? defaultValue : value;
- }
- public Timestamp getTimestamp(Object key) {
- return (Timestamp) get(key);
- }
- public void put(Object... args) {
- for (int i = 1; i ﹤ args.length; i += 2) {
- put(String.valueOf(args[i - 1]), args[i]);
- }
- }
- public JSONObject toJson() {
- return JSONObject.fromObject(this);
- }
- public JSONObject toJson(String... keys) {
- xxx
- }
- public String toJsonString() {
- return toJson().toString();
- }
- }
這個類主要是方便做類型轉換,加入了getInt,getString等方法,另外因為我的系統里面大量使用了JSON,也有一些HashMap向JSON轉換的輔助方法,還有一個特別處理過的put方法和構造器,有什么用呢,看下面的例子
- MapBean params = new MapBean("id",userId,"name",username,"sex",0,"online",true);
如果你直接用HashMap實現以上功能,要寫五行代碼,就這個差別而已,呵呵
當然如果你用JavaBean的話,你也可以寫一個對應的構造函數
接下來,我們在sql-map-config.xml中加入
- ﹤typeAlias alias="mapbean" type="xxxxxxx.MapBean" /﹥
就可以用mapbean的別稱來引用這個類了
例如具體的SQL xml是這樣的
- ﹤select id="getWorkManagerSystemRole" resultClass="mapbean"
- parameterClass="mapbean"﹥
- select * from work_manager_system_role where
- system_id=#system_id# and user_id=#user_id#
- ﹤/select﹥
其實我已經把iBATIS當成SQL wrapper來用了,我曾經評估過Spring的JDBC Template,不過功能始終差少少,或許以后我把JDBC Template再強化一下來代替iBATIS吧。
iBATIS with MapBean應用的淺析就向你介紹到這里,希望對你有所幫助。
【編輯推薦】