千里冰封
          JAVA 濃香四溢
          posts - 151,comments - 2801,trackbacks - 0
          在寫(xiě)JAVAME程序的時(shí)候,我們經(jīng)常需要保存一些數(shù)據(jù)到手機(jī)里面,也經(jīng)常希望能把對(duì)象也保存到手機(jī)里面,但是JAVAME里面沒(méi)有反射機(jī)制,也沒(méi)有java.io.Serializable接口,所以沒(méi)有序列化的機(jī)制,要保存對(duì)象的話(huà),就得自己動(dòng)手了。
          在JAVAME中,程序的數(shù)據(jù)保存的地方,無(wú)外乎兩種,一種是把數(shù)據(jù)保存在RMS里面,這是所有的JAVAME的手機(jī)都支持的,還有一種就是把數(shù)據(jù)保存在手機(jī)的文件系統(tǒng)里面,這個(gè)不是所有手機(jī)都能支持的,只有支持JSR075的手機(jī),才支持把數(shù)據(jù)保存在文件系統(tǒng)里面,并且如果你的程序沒(méi)有經(jīng)過(guò)簽名的話(huà),你每次保存或者讀取,手機(jī)都會(huì)彈出惱人的提示,是否允許程序訪(fǎng)問(wèn)文件系統(tǒng)。所在我一般都是把數(shù)據(jù)存在RMS里面,因?yàn)樽x寫(xiě)RMS是安全的,并且也是不需要手機(jī)提示的。因?yàn)槲覀兊腞MS數(shù)據(jù)是存在一個(gè)特殊的地方。但是JAVAME的RMS功能非常底層,為了保存一些數(shù)據(jù),我們必須和byte[]打交道,所以我就產(chǎn)生了,在此之前封裝一層自己的程序的想法,這樣封裝好以后,使用起來(lái)就非常方便了。只要實(shí)現(xiàn)了相關(guān)接口,就可以享受到比較易用的方法了。

          此框架總共包括了四個(gè)類(lèi),分別如下:
          Serializable類(lèi),它是一個(gè)接口,類(lèi)似于JAVASE里面的Serializable接口,唯一不同的就是,JAVASE里面的接口是一個(gè)空接口,只做標(biāo)記用的,而這里的這個(gè)接口是有方法需要實(shí)現(xiàn)的。
          Lazy類(lèi),它也是一個(gè)接口,它定義了一些方法,如果你的對(duì)象比較大,需要惰性加載的時(shí)候,可以實(shí)現(xiàn)此接口,并且此接口是Serializable接口的子類(lèi),也就是說(shuō)實(shí)現(xiàn)了Lazy接口,你就相當(dāng)于實(shí)現(xiàn)了Serializable接口。
          RMSUtil類(lèi),此類(lèi)是一個(gè)工具類(lèi),用于統(tǒng)一進(jìn)行RMS的相關(guān)操作,也是此框架的核心類(lèi)。
          RecordFetcher類(lèi),也是一個(gè)接口,它繼承了RecordComparator, RecordFilter接口,在取數(shù)據(jù)的時(shí)候,需要用到它。

          好了,下面我們就開(kāi)始看代碼吧。

           1 /*
           2  * To change this template, choose Tools | Templates
           3  * and open the template in the editor.
           4  */
           5 package com.hadeslee.mobile.rms;
           6 
           7 import java.io.IOException;
           8 
           9 /**
          10  * 一個(gè)可自己串行化的類(lèi)所要實(shí)現(xiàn)的接口
          11  * @author hadeslee
          12  */
          13 public interface Serializable {
          14 
          15     /**
          16      * 把自己編碼成字節(jié)數(shù)組的格式
          17      * @return 字節(jié)數(shù)組
          18      */
          19     public byte[] serialize() throws IOException;
          20 
          21     /**
          22      * 把一個(gè)對(duì)象用此字節(jié)數(shù)組進(jìn)行重裝
          23      * @param data 字節(jié)數(shù)組
          24      */
          25     public void unSerialize(byte[] data) throws IOException;
          26 
          27     /**
          28      * 設(shè)置此對(duì)象序列化后對(duì)應(yīng)的存儲(chǔ)對(duì)象的ID
          29      * @param id ID
          30      */
          31     public void setId(int id);
          32 
          33     /**
          34      * 得到此對(duì)象序列化后的ID
          35      * 此方法唯有在反序列化后的對(duì)象上調(diào)用才有效
          36      * 如果一個(gè)對(duì)象是沒(méi)有序列化的,那么它的ID是-1;
          37      * @return ID
          38      */
          39     public int getId();
          40 }
          41 

           1 /*
           2  * To change this template, choose Tools | Templates
           3  * and open the template in the editor.
           4  */
           5 package com.hadeslee.mobile.rms;
           6 
           7 import java.io.IOException;
           8 
           9 /**
          10  * 可以延遲加載的對(duì)象必須要實(shí)現(xiàn)的接口
          11  * @author binfeng.li
          12  */
          13 public interface Lazy extends Serializable {
          14 
          15     /**
          16      * 實(shí)現(xiàn)此接口的類(lèi)要實(shí)現(xiàn)的方法
          17      * 可以用于延遲加載某些屬性。比如
          18      * get("ImgData"),get("fullImage")..等等
          19      * 由于J2ME不支持注釋也不支持反射,所以只能以
          20      * 此種方法來(lái)進(jìn)行模擬了
          21      * 此方法是RMSUtil要存對(duì)象的時(shí)候調(diào)用的,這樣就可以把
          22      * 一個(gè)對(duì)象的不同部份存到不同的RMS里面去了
          23      * @param key 要得到的某性的鍵
          24      * @return 其對(duì)應(yīng)的值
          25      * @throws IOException 
          26      */
          27     public byte[] getAttach(Object key)throws IOException;
          28 
          29     /**
          30      * 當(dāng)把某個(gè)附屬的對(duì)象保存進(jìn)去以后,所要調(diào)用的
          31      * 方法,此方法告訴主體,它的那個(gè)附件被保存后
          32      * 在RMS里面對(duì)應(yīng)的ID是多少
          33      * @param key
          34      * @param id
          35      */
          36     public void savedAttach(Object key, int id);
          37 
          38     /**
          39      * 得到此對(duì)象所支持的所有的key的數(shù)組
          40      * @return KEY的數(shù)組,不能為NULL
          41      */
          42     public Object[] getAttachKeys();
          43 
          44     /**
          45      * 此對(duì)象的附屬對(duì)象所存的RMS的名字
          46      * @return RMS的名字
          47      */
          48     public String getNameOfAttachRMS();
          49 }
          50 

           1 /*
           2  * To change this template, choose Tools | Templates
           3  * and open the template in the editor.
           4  */
           5 package com.hadeslee.mobile.rms;
           6 
           7 import javax.microedition.rms.RecordComparator;
           8 import javax.microedition.rms.RecordFilter;
           9 
          10 /**
          11  * 此類(lèi)是一個(gè)繼承了兩個(gè)接口的接口,并且添加了自己
          12  * 的方法,自己的方法是用于通知數(shù)量以及開(kāi)始取的位置
          13  * 只是為了方便于傳遞參數(shù)以及以后擴(kuò)展
          14  * @author binfeng.li
          15  */
          16 public interface RecordFetcher extends RecordComparator, RecordFilter {
          17 
          18     /**
          19      * 從哪個(gè)下標(biāo)開(kāi)始取
          20      * @return 下標(biāo)
          21      */
          22     public int getFromIndex();
          23 
          24     /**
          25      * 最多取多少條記錄
          26      * @return 記錄
          27      */
          28     public int getMaxRecordSize();
          29 }
          30 

            1 /*
            2  * To change this template, choose Tools | Templates
            3  * and open the template in the editor.
            4  */
            5 package com.hadeslee.mobile.rms;
            6 
            7 import com.hadeslee.mobile.log.LogManager;
            8 import java.util.Enumeration;
            9 import java.util.Hashtable;
           10 import java.util.Vector;
           11 import javax.microedition.rms.RecordEnumeration;
           12 import javax.microedition.rms.RecordStore;
           13 import javax.microedition.rms.RecordStoreException;
           14 
           15 /**
           16  * 一個(gè)專(zhuān)門(mén)用來(lái)操作RMS的工具類(lèi),通過(guò)這個(gè)類(lèi)
           17  * 可以把RMS封裝起來(lái),上層調(diào)用就更方便了
           18  * @author binfeng.li
           19  */
           20 public class RMSUtil {
           21 
           22     /**
           23      * 用于緩存生命周期之內(nèi)的所有的RecordStore的表,當(dāng)MIDlet要退出的
           24      * 時(shí)候,調(diào)用此類(lèi)的關(guān)閉方法,使RMS正確地被關(guān)閉
           25      */
           26     private static Hashtable rmsCache = new Hashtable();
           27 
           28     private RMSUtil() {
           29     }
           30 
           31     /**
           32      * 插入一個(gè)對(duì)象到一個(gè)RMS的數(shù)據(jù)庫(kù)里面,如果此數(shù)據(jù)庫(kù)不存在
           33      * 則自動(dòng)創(chuàng)建一個(gè)對(duì)于MIDlet私有的數(shù)據(jù)庫(kù)。如果存在,則直接
           34      * 插在此數(shù)據(jù)庫(kù)的最后面
           35      * @param ser 要插入的數(shù)據(jù),必須是實(shí)現(xiàn)了Serializable接口的類(lèi)
           36      * @return 是否插入成功
           37      */
           38     public static boolean insertObject(Serializable ser) {
           39         RecordStore rs = null;
           40         try {
           41             rs = getRecordStore(ser.getClass().getName());
           42             if (ser instanceof Lazy) {
           43                 Lazy lazy = (Lazy) ser;
           44                 insertAttachDatas(lazy);
           45             }
           46             byte[] data = ser.serialize();
           47             int id = rs.addRecord(data, 0, data.length);
           48             ser.setId(id);
           49             return true;
           50         } catch (Exception exe) {
           51             exe.printStackTrace();
           52             LogManager.error("RMSUtil.insertObject(),ser = " + ser + ",exe = " + exe);
           53             return false;
           54         }
           55     }
           56 
           57     /**
           58      * 更新某個(gè)對(duì)象到RMS里面去,
           59      * @param ser 要更新的對(duì)象
           60      * @return 是否成功
           61      */
           62     public static boolean updateObject(Serializable ser) {
           63         RecordStore rs = null;
           64         try {
           65             rs = getRecordStore(ser.getClass().getName());
           66             byte[] data = ser.serialize();
           67             rs.setRecord(ser.getId(), data, 0, data.length);
           68             return true;
           69         } catch (Exception exe) {
           70             exe.printStackTrace();
           71             LogManager.error("RMSUtil.updateObject(),ser = " + ser + ",exe = " + exe);
           72             return false;
           73         }
           74     }
           75 
           76     /**
           77      * 從RMS里面刪除某個(gè)對(duì)象
           78      * @param ser 要?jiǎng)h除的對(duì)象
           79      * @return 是否成功
           80      */
           81     public static boolean deleteObject(Serializable ser) {
           82         if (ser.getId() == -1) {
           83             return false;
           84         }
           85         RecordStore rs = null;
           86         try {
           87             rs = getRecordStore(ser.getClass().getName());
           88             int id = ser.getId();
           89             rs.deleteRecord(id);
           90             ser.setId(-1);
           91             return true;
           92         } catch (Exception exe) {
           93             exe.printStackTrace();
           94             LogManager.error("RMSUtil.deleteObject(),ser = " + ser + ",exe = " + exe);
           95             return false;
           96         }
           97     }
           98 
           99     /**
          100      * 從某個(gè)數(shù)據(jù)庫(kù)里面讀取某個(gè)對(duì)象
          101      * @param id 此對(duì)象的ID
          102      * @param clz 對(duì)應(yīng)的類(lèi)
          103      * @return 此對(duì)象,如果發(fā)生任何異常,則返回null
          104      */
          105     public static Serializable readObject(int id, Class clz) {
          106         RecordStore rs = null;
          107         try {
          108             rs = getRecordStore(clz.getName());
          109             byte[] data = rs.getRecord(id);
          110             Serializable ser = (Serializable) clz.newInstance();
          111             ser.unSerialize(data);
          112             ser.setId(id);
          113             return ser;
          114         } catch (Exception exe) {
          115             //如果讀取對(duì)象失敗,則可能是有東西被刪了或者版本不一樣,此時(shí)就應(yīng)該刪掉
          116             exe.printStackTrace();
          117             LogManager.error("RMSUtil.readObject(),id = " + id + ",Class = " + clz + ",exe= " + exe);
          118             if (rs != null) {
          119                 try {
          120                     rs.deleteRecord(id);
          121                 } catch (Exception ex) {
          122                     ex.printStackTrace();
          123                     LogManager.error("RMSUtil.readObject$rs.deleteRecord(id),id = " + id + ",exe = " + ex);
          124                 }
          125             }
          126             return null;
          127         }
          128     }
          129 
          130     /**
          131      * 得到某個(gè)類(lèi)存在RMS里面的總數(shù),這樣便于分段取
          132      * @param cls 類(lèi)名
          133      * @return 有效記錄總數(shù)
          134      */
          135     public static int getStoreSize(Class cls) {
          136         try {
          137             RecordStore rs = getRecordStore(cls.getName());
          138             return rs.getNumRecords();
          139         } catch (Exception exe) {
          140             exe.printStackTrace();
          141             LogManager.error("RMSUtil.getStoreSize(),Class = " + cls + ",exe = " + exe);
          142             return -1;
          143         }
          144     }
          145 
          146     /**
          147      * 列出某個(gè)類(lèi)的對(duì)象的集合,最多取多少個(gè)對(duì)象
          148      * @param cls 類(lèi)名
          149      * @param from 從第幾個(gè)開(kāi)始取
          150      * @param maxSize 最多取多少個(gè)對(duì)象
          151      * @return 取到的列表
          152      */
          153     public static Vector listObjects(Class cls, int from, int maxSize) {
          154         System.out.println("class="+cls);
          155         if (from < 0 || maxSize < 1) {
          156             throw new IllegalArgumentException("from can not less than 0 and maxSize must greater than 0");
          157         }
          158         Vector v = new Vector();
          159         RecordEnumeration ren = null;
          160         try {
          161             RecordStore rs = getRecordStore(cls.getName());
          162             ren = rs.enumerateRecords(nullnullfalse);
          163             fetchRecord(v, cls, ren, from, maxSize);
          164         } catch (Exception exe) {
          165             LogManager.error("RMSUtil.listObjects(),Class = " + cls + ",from = " + from + ",maxSize = " + maxSize + ",exe = " + exe);
          166             exe.printStackTrace();
          167         } finally {
          168             ren.destroy();
          169         }
          170         return v;
          171     }
          172 
          173     /**
          174      * 用于前面一個(gè)方法和后面一個(gè)方法的共用方法,
          175      * 它用來(lái)從特定的記錄枚舉里面去取特定的記錄,
          176      * 并放到特定的地方
          177      * @param v 要保存的地方
          178      * @param cls 要實(shí)例化的類(lèi)
          179      * @param ren 記錄的枚舉
          180      * @param from 從哪里開(kāi)始取
          181      * @param maxSize 要取多少條記錄
          182      * @throws java.lang.Exception 可能會(huì)拋出的異常
          183      */
          184     private static void fetchRecord(Vector v, Class cls, RecordEnumeration ren, int from, int maxSize) throws Exception {
          185         int index = 0;
          186         int size = 0;
          187         while (ren.hasNextElement()) {
          188             int id = ren.nextRecordId();
          189             if (index >= from) {
          190                 if (size < maxSize) {
          191                     Serializable ser = readObject(id, cls);
          192                     if (ser != null) {
          193                         v.addElement(ser);
          194                         size++;
          195                     }
          196                 } else {
          197                     break;
          198                 }
          199             }
          200             index++;
          201         }
          202     }
          203 
          204     /**
          205      * 列出某個(gè)類(lèi)的對(duì)象,并用一種過(guò)濾以及排序的方法來(lái)進(jìn)行過(guò)濾或者排序
          206      * @param cls 類(lèi)名
          207      * @param fetcher 取記錄的方法
          208      * @return 記錄列表
          209      */
          210     public static Vector listObjects(Class cls, RecordFetcher fetcher) {
          211         System.out.println("fetcher class="+cls);
          212         int from = fetcher.getFromIndex();
          213         int maxSize = fetcher.getMaxRecordSize();
          214         if (from < 0 || maxSize < 1) {
          215             throw new IllegalArgumentException("from can not less than 0 and maxSize must greater than 0");
          216         }
          217         Vector v = new Vector();
          218         RecordEnumeration ren = null;
          219         try {
          220             RecordStore rs = getRecordStore(cls.getName());
          221             ren = rs.enumerateRecords(fetcher, fetcher, false);
          222             fetchRecord(v, cls, ren, from, maxSize);
          223         } catch (Exception exe) {
          224             LogManager.error("RMSUtil.listObjects(),Class = " + cls + ",exe = " + exe);
          225             exe.printStackTrace();
          226         } finally {
          227             ren.destroy();
          228         }
          229         return v;
          230     }
          231 
          232     /**
          233      * 插入某個(gè)可延遲加載的對(duì)象的所有附件到數(shù)據(jù)庫(kù)里面去
          234      * 插入完成后,此lazy對(duì)象將變得很完整,因?yàn)榇藭r(shí)它的
          235      * 附件對(duì)象的ID都已經(jīng)設(shè)置好了
          236      * @param lazy 要插入附件的主對(duì)象
          237      * @return 是否插入成功
          238      */
          239     private static boolean insertAttachDatas(Lazy lazy) {
          240         try {
          241             Object[] attachKeys = lazy.getAttachKeys();
          242             RecordStore rs = getRecordStore(lazy.getNameOfAttachRMS());
          243             for (int i = 0; i < attachKeys.length; i++) {
          244                 Object key = attachKeys[i];
          245                 byte[] data = lazy.getAttach(key);
          246                 int id = rs.addRecord(data, 0, data.length);
          247                 lazy.savedAttach(key, id);
          248             }
          249             return true;
          250         } catch (Exception exe) {
          251             exe.printStackTrace();
          252             LogManager.error("RMSUtil.insertAttachDatas(),Lazy = " + lazy + ",exe = " + exe);
          253             return false;
          254         }
          255     }
          256 
          257     /**
          258      * 得到某個(gè)可以延遲加載的對(duì)象的某個(gè)附件的字節(jié)數(shù)組內(nèi)容
          259      * TODO 如果能把此方法變成私有,那就更好了
          260      * 此方法是專(zhuān)門(mén)供lazy對(duì)象調(diào)用的,這樣的話(huà),實(shí)體類(lèi)里面就出現(xiàn)了
          261      * 讀取數(shù)據(jù)的方法,但是由于J2ME不支持反射,只能這樣實(shí)現(xiàn)了
          262      * @param lazy 可以延遲加載的對(duì)象
          263      * @param id 附件的ID
          264      * @return 對(duì)應(yīng)的數(shù)組
          265      */
          266     public static byte[] getAttachData(Lazy lazy, int id) {
          267         try {
          268             return getRecordStore(lazy.getNameOfAttachRMS()).getRecord(id);
          269         } catch (Exception exe) {
          270             exe.printStackTrace();
          271             LogManager.error("RMSUtil.getAttachData(),Lazy = " + lazy + ",id = " + id + ",exe = " + exe);
          272             return null;
          273         }
          274     }
          275 
          276     /**
          277      * 更新某個(gè)對(duì)象的附件
          278      * TODO 如果能把此方法變成私有就更好了
          279      * @param lazy 可延遲加載的對(duì)象
          280      * @param id 附件的ID
          281      * @param data 附件的內(nèi)容
          282      * @return 是否成功
          283      */
          284     public static boolean updateAttachData(Lazy lazy, int id, byte[] data) {
          285         try {
          286             RecordStore rs = getRecordStore(lazy.getNameOfAttachRMS());
          287             rs.setRecord(id, data, 0, data.length);
          288             return true;
          289         } catch (Exception exe) {
          290             exe.printStackTrace();
          291             LogManager.error("RMSUtil.updateAttachData(),Lazy = " + lazy + ",exe = " + exe);
          292             return false;
          293         }
          294     }
          295 
          296     /**
          297      * 從附件數(shù)據(jù)庫(kù)中刪除某個(gè)附件
          298      * @param lazy 主對(duì)象
          299      * @param id 附件的ID
          300      * @return 是否刪除成功
          301      */
          302     public static boolean deleteAttachData(Lazy lazy, int id) {
          303         try {
          304             RecordStore rs = getRecordStore(lazy.getNameOfAttachRMS());
          305             rs.deleteRecord(id);
          306             return true;
          307         } catch (Exception exe) {
          308             exe.printStackTrace();
          309             LogManager.error("RMSUtil.deleteAttachData(),Lazy = " + lazy + ",id = " + id + ",exe = " + exe);
          310             return false;
          311         }
          312     }
          313 
          314     /**
          315      * 關(guān)閉所有的RMS
          316      */
          317     public static void closeAllRMS() {
          318         Enumeration en = rmsCache.elements();
          319         while (en.hasMoreElements()) {
          320             RecordStore rs = (RecordStore) en.nextElement();
          321             closeRecordStore(rs);
          322         }
          323         rmsCache.clear();
          324     }
          325 
          326     public static void deleteRecord(Class cls, int id) {
          327         deleteRecord(cls.getName(), id);
          328     }
          329 
          330     /**
          331      * 刪除某個(gè)倉(cāng)庫(kù)里面的某條記錄
          332      * @param rsName 倉(cāng)庫(kù)的名字
          333      * @param id 記錄的ID
          334      */
          335     public static void deleteRecord(String rsName, int id) {
          336         try {
          337             RecordStore rs = RecordStore.openRecordStore(rsName, false);
          338             if (rs != null) {
          339                 rs.deleteRecord(id);
          340             }
          341             rs.closeRecordStore();
          342         } catch (Exception exe) {
          343         }
          344     }
          345 
          346     /**
          347      * 一個(gè)簡(jiǎn)單的方法用于關(guān)閉RecordStore
          348      * @param rs 要關(guān)閉的RecordStore
          349      */
          350     private static void closeRecordStore(RecordStore rs) {
          351         try {
          352             rs.closeRecordStore();
          353         } catch (Exception exe) {
          354             LogManager.error("RMSUtil.closeRecordStore(),rs = " + rs + ",exe = " + exe);
          355             exe.printStackTrace();
          356         }
          357     }
          358 
          359     /**
          360      * 得到某個(gè)RMS的存儲(chǔ)數(shù)據(jù)庫(kù),先從緩存里面去找,如果沒(méi)有找到則生成
          361      * 一個(gè)并把它放到緩存里面,還有,因?yàn)镽MS的名字,最長(zhǎng)只支持32位
          362      * @param name 數(shù)據(jù)庫(kù)的名字
          363      * @return 找到的RMS數(shù)據(jù)庫(kù)
          364      */
          365     private synchronized static RecordStore getRecordStore(String name) throws RecordStoreException {
          366         if (name.length() > 32) {
          367             name = name.substring(name.length()-32, name.length());
          368         }
          369         if (rmsCache.containsKey(name)) {
          370             return (RecordStore) rmsCache.get(name);
          371         } else {
          372             RecordStore rs = RecordStore.openRecordStore(name, true);
          373             rmsCache.put(name, rs);
          374             return rs;
          375         }
          376     }
          377 }
          378 


          相信看完代碼以后,大家應(yīng)該知道如何使用它吧。如果有需要持久化的類(lèi),那么就需要實(shí)現(xiàn)Serializable接口,然后只要調(diào)用RMSUtil.insertObject()就可以了,同理,查找也是一樣的,你可以查找同一個(gè)類(lèi)的一系列對(duì)象,也可以自己定義記錄查詢(xún)器,在里面設(shè)置查詢(xún)條件。
          目前JAVAME的持久化框架,也有用其它的方法實(shí)現(xiàn)的,比如動(dòng)態(tài)插入代碼的方法,也就是你在寫(xiě)好了JAVAME的代碼以后,在編譯的過(guò)程中,它自動(dòng)幫你加上相應(yīng)的方法,我看了一個(gè)他們的源碼,其實(shí)也就是它們自己幫你實(shí)現(xiàn)了一個(gè)相當(dāng)于Serializable接口,我覺(jué)得這樣不好的地方在于,它會(huì)為你的類(lèi)添加方法,萬(wàn)一你的類(lèi)里面原來(lái)就有那個(gè)方法的時(shí)候,那就會(huì)出現(xiàn)不可意料的情況了,還有,我覺(jué)得自己的數(shù)據(jù)還是自己一個(gè)一個(gè)把它寫(xiě)出來(lái),這樣心里更踏實(shí)一些。我一直都認(rèn)為,封裝得有一個(gè)度,不能過(guò)度的封裝,過(guò)度封裝表面上看是編碼更方便了,但是寫(xiě)的時(shí)候,自己心里也更沒(méi)底了,因?yàn)槟悴恢绖e人的代碼都做了一些什么。因?yàn)閯e人的代碼做的事情太多了。呵呵,純屬個(gè)人意見(jiàn)。
          大家如果有什么自己的看法,歡迎留言。
          還有,此代碼用到了我的另外一個(gè)通用框架,那就是LOG框架,所以如果直接下載的話(huà),可能會(huì)編譯不過(guò)了,只要注釋掉LogManager的調(diào)用就可以了。LOG框架的說(shuō)明點(diǎn)擊這里,這個(gè)LOG框架現(xiàn)在正在改動(dòng)中,以使它更好用,更沒(méi)有侵入性。

          Netbeans項(xiàng)目工程打包下載,請(qǐng)點(diǎn)擊這里。此工程中還有LOG框架在里面。




          盡管千里冰封
          依然擁有晴空

          你我共同品味JAVA的濃香.
          posted on 2009-03-01 10:13 千里冰封 閱讀(5065) 評(píng)論(3)  編輯  收藏 所屬分類(lèi): JAVAME

          FeedBack:
          # re: JAVAME的RMS通用持久化框架[未登錄](méi)
          2009-03-01 08:38 | Aaron
          謝謝樓主的分享,非常好的文章  回復(fù)  更多評(píng)論
            
          # re: JAVAME的RMS通用持久化框架
          2009-03-01 09:58 | foot
          樓主學(xué)習(xí)的速度很快啊。  回復(fù)  更多評(píng)論
            
          # re: JAVAME的RMS通用持久化框架
          2009-05-20 15:57 | f
          javamE已死  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 石阡县| 宁南县| 通州市| 池州市| 肇东市| 沙河市| 通河县| 永仁县| 石嘴山市| 长宁县| 武宣县| 四平市| 固原市| 抚顺县| 龙陵县| 安乡县| 泌阳县| 苏州市| 环江| 富平县| 孝昌县| 松原市| 漾濞| 吐鲁番市| 巴塘县| 西青区| 洛宁县| 眉山市| 阿拉善左旗| 莲花县| 澄江县| 舟山市| 临武县| 秦安县| 新沂市| 庆元县| 吉水县| 衡阳市| 宽甸| 明水县| 奈曼旗|