Android – 資料存取機制 – 存取本機資料庫結構

在專案運作過程中, 除了專案原始碼加上專案資源檔案編譯為.apk之後, 當使用者在執行app的時候會需要將相關資料進行儲存及使用時, 就將是本章節所要探討的資料儲存存取機制.

有以下幾個主要的面向來進行探討:

  • 使用者的偏好設定
  • 專屬於app的檔案資料
  • 可以共用的檔案資料
  • 存取本機資料庫結構
  • 讀取專案特定資源資料

SQLite 資料庫


開發應用程式運用的資料庫系統來處理大量資料,使用SQL查詢語法可以迅速地過濾出想要的資料,這應該是資料庫系統有別於一般文件輸入輸出的優勢,一樣是存放資料,但是放在資料庫中的資料比較具有使用上的意義,而以一般文件存放資料的缺點就是查詢過濾的複雜性與效能性遠低於資料庫。Android完全支持SQLite資料庫系統。

建立合約類別


當在建立資料庫時會針對資料庫組織方式做正式宣告,使用SQL陳述式來反映這個資料庫的結構描述。為了方便管理資料庫的結構描述,建立合約類別能以系統化的自我記錄方式,反映這個資料庫的結構描述。例:當您想修改某個欄位名稱,只要在建立的合約類別裡進行修改,然後將其傳播到全部程式碼中。

一個合約類別的普遍寫法,是將整個資料庫的全域定義置於類別的根層級,然後再對表格建立內部類別來管理。如下建立一個表格的名稱與其欄位名稱。

public class MyContract {

   public MyContract() {}

   public static abstract class MyTable1 implements BaseColumns {
       public static final String TABLE_NAME = "cust";
       public static final String COLUMN_NAME_NAME = "name";
       public static final String COLUMN_NAME_TEL = "title";
       public static final String COLUMN_NAME_BIRTHDAY = "birthday";
   }
}

 

建立資料庫輔助類別物件


自行開發一個子類別繼承SQLiteOpenHelper類別,用於建立資料庫與資料表。

實作方式如下:

  • Override:onCreate(SQLiteDatabase db)
  • Override:onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
  • 定義建構式 MyDbHelper(Context context)
public class MyDbHelper extends SQLiteOpenHelper {

   public MyDbHelper(Context context , int version) {
       super(context, DATABASE_NAME, null, version);
   }

   @Override
   public void onCreate(SQLiteDatabase db) {
       db.execSQL(SQL_CREATE_ENTRIES);
   }

   @Override
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
       db.execSQL(SQL_DELETE_ENTRIES);
       onCreate(db);
   }

}

將之前建立的合約類別import進來然後在類別底下建立維護資料庫的陳述式,如建立資料庫、刪除資料庫、資料庫版本以及資料庫的名稱等。

public static final String DATABASE_NAME = "MyDbHelper.db";

private static final String TEXT_TYPE = " TEXT";
private static final String DATE_TYPE = " DATE";
private static final String COMMA_SEP = ",";

private static final String SQL_CREATE_ENTRIES =
       "CREATE TABLE " + MyTable1.TABLE_NAME + " (" +
               MyTable1._ID + " INTEGER PRIMARY KEY," +
               MyTable1.COLUMN_NAME_NAME + TEXT_TYPE + COMMA_SEP +
               MyTable1.COLUMN_NAME_TEL + TEXT_TYPE + COMMA_SEP +
               MyTable1.COLUMN_NAME_BIRTHDAY + DATE_TYPE + COMMA_SEP +
               " )";
private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS " + MyTable1.TABLE_NAME;

 

操作資料庫


首先宣告MyDbHelper與SQLiteDatabase物件實體

private MyDbHelper myDbHelper;
private SQLiteDatabase database;

 

接著呼叫使用MyDbHelperget物件方法getReadableDatabase()或是getWritableDatabase()回傳SQLiteDatabase物件存放在database變數。兩者的差異在於使用者的儲存空間不足的情況之下,getReadableDatabase()仍然可以開啟使用,只是處在唯讀的模式,一旦使用者釋放出足夠的儲存空間,則又可以開始進行讀寫模式;而getWritableDatabase()則在使用者的儲存空間不足的情況之下,直接拋出Exception,開發者將會針對該Exception進行try….catch的開發結構來處理。

myDbHelper = new MyDbHelper(this,1);
database = myDbHelper.getReadableDatabase();

 

新增資料


呼將ContentValues 物件實體的put(Key,Value)方法包裝資料,將字串字元當作其Key,而資料值放在第二的參數傳遞。然後將包裝好的資料傳遞給SQLiteDatabase物件實體的insert()方法,可將資料插入至資料庫。

SQLiteDatabase物件實體的insert(),傳第三個參數:

  • 資料表名稱
  • null:通常設定為null
  • 資料內容
ContentValues values = new ContentValues();
values.put(MyTable1.COLUMN_NAME_NAME, "Neo");
values.put(MyTable1.COLUMN_NAME_TEL, "0999-123456");
values.put(MyTable1.COLUMN_NAME_BIRTHDAY, "2000-12-12");

long newRowId;
newRowId = database.insert(MyTable1.TABLE_NAME,null,values);

可以建立long變數來獲取新增的資料ID,也可以不用直接使用database.insert();

 

查詢資料


查詢剛剛新增的資料,若要對資料庫進行讀取需要呼叫使用SQLitDatabase物件實體的query方法,在完成查詢後query()會回傳Cursor物件實體。

query()傳遞六個參數來進行查詢操作:

  • 資料表名稱
  • 查詢條件式
  • 查詢條件值字元串
  • 對行進行分組
  • 按行組過濾
  • 排列順序

 

這裡撰寫最簡單也最常用的查詢語法:SELECT * FROM cust。這裡查詢語法只需用到資料表名稱,其餘的參數如果不需使用的話只需填入null。

Cursor c = database.query( MyTable1.TABLE_NAME, null,null, null, null,null, null);

使用Cursor 物件實體的方法來對查詢的資料進行操作:

  • moveToNext():使查詢指針往下一筆資料移動,當沒任何資料時回傳false。
  • getCount():傳回查詢結果的資料筆數。
  • getColumnIndex():指定查詢域名,傳回其結果字串的index。
  • getString():指定字串index,傳回該筆資料內容。

如下,將查詢到的資料內容裡欄位名稱為合約類別的COLUMN_NAME_NAME值顯示在畫面上。

while (c.moveToNext()) {
   textView.append(c.getString(c.getColumnIndex(MyTable1.COLUMN_NAME_NAME)));
}

刪除資料


直接呼叫使用SQLiteDatabase物件時體的delete(),傳遞三個參數:

  • 資料表名稱
  • 查詢條件式
  • 查詢條件值字元串數組

以下列SQL語法為例:

DELETE FROM cust WHERE name like ‘Neo’

則會寫成:

database.delete(
MyTable1.TABLE_NAME, 
MyTable1.COLUMN_NAME_NAME + " =  ? ",
new String[] { "Neo" });

修改資料


直接呼叫使用SQLiteDatabase物件時體的update(),傳遞4個參數:

  • 資料表名稱
  • 修改的資料內容
  • 查詢條件式
  • 查詢條件值字元串數組

以下列SQL語法為例:

UPDATE cust SET name = ‘Morpheus’  WHERE name = ‘Neo’

如下實做:

ContentValues values = new ContentValues();
values.put(MyTable1.COLUMN_NAME_NAME, "Morpheus");

database.update(
MyTable1.TABLE_NAME,
 values,
MyTable1.COLUMN_NAME_NAME,
 new String[] {"Neo"});

 

 

 

 

本站資源一切隨緣,
不用註冊, 不看廣告
如果對您有所助益,
歡迎功德隨喜, 金額隨意,
請點擊以下...(感謝您)

功德箱/打賞箱

%d bloggers like this: