程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 打造自己的RMS框架

打造自己的RMS框架

編輯:關於.NET

RMS提供的記錄操作可以實現根據ID直接獲得記錄,或者枚舉出一個表中的所有記錄。

但是枚舉記錄的效率是非常低的,因為只能比較byte[]數據來確定該記錄是否是所需要的記錄。通過ID獲得記錄是高效而方便的,類似於SQL語句中”selecte byteArrayData from recordStoreName where RecordID = ?”。然而,通常應用程序很難知道某條激流的ID號,而RMS記錄的“主鍵”又僅限於int類型,無法使用其他類型如String作為“主鍵”來查找。因此,對於需要存取不同類型對象的應用程序而言,就需要一個靈活的RMS操作框架。

我們的基本設想是,如果能使用String作為“主鍵”來查找記錄,就能非常方便地獲得所需的內容。例如,應用程序設置可以通過"sys.settings"獲得byte[]數組,並依次讀取出設置,用戶登錄信息可以通過"user.info"獲得byte[]數組,再分解出用戶名和口令。

因此,我們實現一個StorageHandler類,提供唯一的RMS訪問接口,使得其他類完全不必考慮底層的RMS操作,只需提供能標識自身的一個String即可。

如果我們能實現一種類似於數據庫索引的查找表,就能根據String關鍵字查找某條記錄。因此,我們使用一個名為"index"的RecordStore來存儲所有的索引,每一條索引都指向某一條具體記錄的ID,設計一個IndexEntry表示一條索引:

class IndexEntry {
   private int selfId;  // IndexEntry的ID
   private int recordId; // 對應記錄的ID
   private String key;  // 訪問記錄的Key
}

根據索引查找,分3步進行:

1.在名為"index"的RecordStore中根據String查找對應的IndexEntry。

2.取出IndexEntry,獲得記錄ID號。

3.根據ID號獲得另一個RecordStore的記錄,然後就可以讀取、更新和刪除該記錄。

根據網上的那一篇J2ME最佳實踐之RMS操作(建議先看看這篇),我寫了一個自己的RMS框架,包含完整的代碼。

首先看看示意圖,示意圖總是看著讓我思路清晰一些。

這幅圖摘自J2ME最佳實踐之RMS操作,很明顯我需要兩個RecordStore,一個index存儲String類型的主鍵和RecordId,另一個data存儲記錄。

我為我的RMS框架也做了一份示意圖,從圖中可以看出我的類結構

RecordManager——用於操作RecordStore的類,提供了一些操作RMS的基本方法

StoreHandler——倉庫處理類,提供了LoadData、StoreData、StoreIndex方法

IndexEntry——主鍵、記錄ID實體類,對應上圖RecordStore中的index

IStore——接口,提供SaveData(保存數據)、ReadData(讀取數據)的方法,需要進行存儲的對象,只需要對象對應的類實現IStore接口

User,Person——實體類,實現IStore接口

RecordManager類:

package com.org.sunny.rms;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
/**
  *
  * @author Administrator
  */
public class RecordManager {

   //RMS是否打開
   boolean isOpen = false;
   public RecordStore rs;
   /**
    * 打開RMS,分別可以傳入index和data
    * index存儲主鍵、RecordId
    * data存儲數據
    * @param rsName
    */
   public void open(String rsName) {
     try {
       rs = RecordStore.openRecordStore(rsName, true, RecordStore.AUTHMODE_ANY, true);
     } catch (RecordStoreException ex) {//存儲系統異常
       System.out.print(ex);
     } catch (IllegalArgumentException ex) {//參數錯誤異常
       System.out.println(ex);
     }
   }
   /**
    * 關閉RMS
    */
   public void close() {
     try {
       rs.closeRecordStore();
     } catch (Exception ex) {
       ex.printStackTrace();
     }
   }
   /**
    * 添加一條記錄,並返回添加的記錄ID
    * @param rsName
    * @param data
    * @return
    */
   public int add(String rsName, byte[] data) {
     int recordId = 0;
     open(rsName);
     try {
       recordId = rs.addRecord(data, 0, data.length);
     } catch (Exception ex) {
       ex.printStackTrace();
     }
     return recordId;
   }
   /**
    * 通過key獲取記錄ID
    * @param rsName
    * @param key
    * @return
    * @throws java.io.IOException
    */
   public int getRecordId(String rsName, String key) throws IOException {
     int recordId = 0;
     try {
       open(rsName);
       IndexEntry index = new IndexEntry();
       int total = rs.getNumRecords();
       byte[] data;
       for (int i = 0; i < total; i++) {
         data = rs.getRecord(i + 1);
         ByteArrayInputStream bais = new ByteArrayInputStream(data, 0, data.length);
         DataInputStream dis = new DataInputStream(bais);
         //獲取recordId,key
         index.ReadKey(dis);
         if (key.equals(index.key)) {//如果讀取的key和傳入的key相同,跳出循環
           recordId = index.recordId;
           dis.close();
           bais.close();
           break;
         }
       }
     } catch (RecordStoreException ex) {
       ex.printStackTrace();
     }
     close();
     return recordId;
   }
   /**
    * 通過key獲取記錄
    * @param rsName
    * @param key
    * @return
    * @throws java.io.IOException
    */
   public byte[] get(String rsName, String key) throws IOException {
     open(rsName);
     byte[] data = null;
     int recordId = getRecordId(StoreHandler.INDEX_RS, key);
     data = get(rsName, recordId);
     close();
     return data;
   }
   /**
    * 通過記錄ID獲取記錄
    * @param rsName
    * @param recordId
    * @return
    */
   public byte[] get(String rsName, int recordId) {
     open(rsName);
     byte[] data = null;
     try {
       data = rs.getRecord(recordId);
     } catch (RecordStoreException ex) {
       ex.printStackTrace();
     }
     close();
     return data;
   }
}

IStore接口:

package com.org.sunny.rms;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
  *
  * @author Administrator
  */
public interface IStore {
   String getKey();
   //存入數據
   void SaveData(DataOutputStream output) throws IOException;
   //獲取數據
   void ReadData(DataInputStream input) throws IOException;
}

IndexEntry類:

package com.org.sunny.rms;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
  *
  * @author Administrator
  */
public class IndexEntry {
   public int selfId;
   public int recordId;
   public String key;
   public void SaveKey(DataOutputStream output) throws IOException {
     //注意這裡output是按照順序來寫的,取出來的時候也安裝這種順序來讀
     //這樣就能解決一條數據有多列,而又不必去可以添加分隔符
     output.writeInt(recordId);
     output.writeUTF(key);
   }
   public void ReadKey(DataInputStream input) throws IOException {
     recordId = input.readInt();
     key = input.readUTF();
   }
}

User類:

package com.org.sunny.rms;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
  *
  * @author Administrator
  */
public class User implements IStore {
   int id;
   String name;
   String sex;
   int age;
   String city;
   String description;
   public String getKey() {
     //由於從服務器獲取數據時,每條數據都有一個相應的int類型的主鍵ID(這個是唯一的)
     //所以我在構造key時根據:類+數據庫的主鍵ID
     //這樣不僅能夠確保唯一性,而且從key中我就能夠知道這條數據的含義
     return "user.info" + id;
   }
   //存入數據
   public void SaveData(DataOutputStream output) throws IOException {
     //注意這裡output是按照順序來寫的,取出來的時候也安裝這種順序來讀
     //這樣就能解決一條數據有多列,而又不必去可以添加分隔符
     output.writeUTF(name);
     output.writeUTF(sex);
     output.writeInt(age);
     output.writeUTF(city);
     output.writeUTF(description);
   }
   //取出數據
   public void ReadData(DataInputStream input) throws IOException {
     name = input.readUTF();
     sex = input.readUTF();
     age = input.readInt();
     city = input.readUTF();
     description = input.readUTF();
   }
}

StoreHandler類(很關鍵的一個類):

package com.org.sunny.rms;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
  *
  * @author Administrator
  */
public class StoreHandler {
   RecordManager rm = new RecordManager();
   public static final String INDEX_RS = "index";
   public static final String DATA_RS = "data";
   /**
    * 存入數據對應的key
    * @param index
    */
   public void StoreIndex(IndexEntry index) throws IOException {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(baos);
     //寫入key
     index.SaveKey(dos);
     byte[] key = baos.toByteArray();
     String keyName = new String(key);
     System.out.println("keyName" + keyName);
     dos.close();
     baos.close();
     rm.add(INDEX_RS, key);
   }
   /**
    * 存入數據
    * @param store
    * @throws java.io.IOException
    */
   public void StoreData(IStore store) throws IOException {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(baos);
     //寫入數據
     store.SaveData(dos);
     byte[] data = baos.toByteArray();
     int recordId = rm.add(DATA_RS, data);
     IndexEntry index = new IndexEntry();
     index.recordId = recordId;
     index.key = store.getKey();
     //關閉流
     dos.close();
     baos.close();
     //存入唯一的key
     StoreIndex(index);
   }
   /**
    * 讀取數據
    * @param store
    * @throws java.io.IOException
    */
   public IStore LoadData(IStore store) throws IOException {
     byte[] data = rm.get(DATA_RS, store.getKey());
     ByteArrayInputStream bais = new ByteArrayInputStream(data, 0, data.length);
     DataInputStream dis = new DataInputStream(bais);
     //給Store類的各個屬性賦值
     store.ReadData(dis);
     //關閉流
     dis.close();
     bais.close();
     return store;

   }
}

下面是我進行測試的界面和結果:

一個SaveForm,一個ReadForm。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved