摘要
在行動應用程式中,使用一個如 SQLite 等簡單的後端資料庫在許多使用場合下會很有用。本文將探討 Android* SQLite API 以及 helper 類別在資料庫的建立和維護上的用途。我們會討論如何建立並使用預先載入的資料庫,以及如何使用 SQLite 公用程式庫來為範例的餐廳應用程式實作一個資料庫後端。
目錄
概觀
通用的 Android SQLite API 可讓開發者實作所有的資料庫處理功能,包括資料庫的建立、版本控制、資料庫升級以及其他自訂功能。若想要使用一個預載入的 SQLite 資料庫,則需要進行額外的設定。
直接使用 Android SQLite API 可能會導致許多未定案程式碼因而產生。有好幾個 Android 公用程式庫可讓此過程更輕鬆,還能提供各種方便的額外功能,讓在 Android 應用程式中使用 SQLite 資料庫變得既輕鬆又有效率。
零售業餐廳範例應用程式 - Little Chef
我們將會使用範例應用程式 (Little Chef) 探討 SQLite 資料庫和 SQLiteAssetHelper 程式庫的使用。
使用者可以用這個應用程式瀏覽各類餐點和菜色。
圖 1:餐廳範例應用程式 - Little Chef
廚師或業主可以用餐廳應用程式來檢視各類餐點和菜色。該範例應用程式是以滑動手勢來切換不同的餐點類別,還能選取各項菜色來讀取詳細資訊。
A SQLite 資料庫可用於儲存菜單類別及菜色的詳細資訊。該應用程式的未來版本將會延伸資料庫以支援其他種類的應用程式資料,如銷售資料、客戶忠誠度計畫、單一客戶的自訂化功能等。
使用既有的資料庫
根據應用程式的需求,可以預先載入初始資料集。在餐廳範例應用程式中已預先填入標準的菜單類別和菜色詳細資訊的基本設置。
可使用 Android API (如 SQLiteOpenHelper) 來填入資料的初始設置,當作資料庫的建立與初始化的一部分。然而這不一定會是最好的方法,特別是當資料集很龐大的時候。另外有些SQLiteOpenHelper 呼叫並不建議在主執行中使用。依據裝置功能的不同,使用者可能會在啟動時遭遇到緩慢的初始化和 UI 延遲的情況。另外一個方式是預先填入資料庫,並將資料庫封裝為應用程式資產的一部分。
例如我們用 SQLite 的 python 編程 API 為餐廳範例應用程式建立了一個 SQLite 離線資料庫。同時也有 GUI 用戶端,以供手動編輯或在 SQLite 資料庫中加入資料。如同 Android SQLite API 文件所建議,加入了「_id」欄以供獨立辨識各行。這個欄位在內容供應器和轉接器摘要的實作上相當實用。
若要以 Android SQLite API 自應用程式的資產中存取 SQLite 資料庫,必須將資料庫檔案從資產資料夾中複製到應用程式的資料庫資料夾路徑。資料夾升級和版本控制的支援工作讓這項工作變得更加複雜。
我們在「assets」資料夾下建立了一個「database」資料夾,並將預載完成的「restaurant.sqlite」檔案複製至「database」資料夾。詳細的實作資訊請參閱下列程式碼片段。
package com.example.restaurant;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
/**
* Database handler for restaurant app.
*/
public class RestaurantDatabase extends SQLiteAssetHelper {
private static final String TAG = SQLiteAssetHelper.class.getSimpleName();
private static final String DATABASE_NAME = "restaurant.sqlite";
private static final int DATABASE_VERSION = 1;
public interface TABLES {
String MENU = "menu";
String USER = "user";
String CUSTOMER = "customer";
}
public interface MenuColumns {
String CATEGORY = "category";
String NAME = "name";
String DESCRIPTION = "description";
String NUTRITION = "nutrition";
String PRICE = "price";
String IMAGENAME = "imagename";
}
public RestaurantDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public Cursor getMenuItems() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLES.MENU);
Cursor c = qb.query(db, null, null, null, null, null, null);
c.moveToFirst();
return c;
}
}
程式碼片段 1,採用預載入資料庫 ++
自餐廳資料庫存取菜單項目
初始化時,SQLiteAssetHelper 會自動從資產資料夾中將預載入的餐廳資料庫複製至適當的資料庫路徑。後續呼叫將重複使用該資料庫實例,除非有升級請求。上述的程式碼片段顯示的是getMenuItems 方法,會為資料庫內的所有菜單菜色傳回一個游標。
下列程式碼片段顯示的是資料庫實例的建立,並自游標解析菜單菜色。
mDb = new RestaurantDatabase(this);
mMenuItems = new ArrayList<MenuItem>();
Set<String> categories = new HashSet<String>();
Cursor c = mDb.getMenuItems();
while (c.moveToNext()) {
String category = c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.CATEGORY));
categories.add(category);
MenuItem menuItem = new MenuItem();
menuItem.setCategory(category);
menuItem.setName(c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.NAME)));
menuItem.setDescription(c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.DESCRIPTION)));
menuItem.setNutrition(c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.NUTRITION)));
menuItem.setPrice(c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.PRICE)));
menuItem.setImageName(c.getString(c.getColumnIndexOrThrow(RestaurantDatabase.MenuColumns.IMAGENAME)));
mMenuItems.add(menuItem);
}
c.close();
mCategoryList = new ArrayList<String>(categories);
程式碼片段 2:自餐廳資料庫存取菜單項目 ++
不建議在主線程中處理資料庫的存取。我們可以使用 SQLiteAssetHelper 加入額外的提取功能,如 Android 內容供應器介面。
根據應用程式需求和使用場合,可為餐聽範例應用程式加入更多功能,例如資料庫升級支援、版本控制、甚至是後端伺服器支援。如果是實作後端伺服器資料庫,可將應用程式的本機 SQLite 資料庫作為暫時性的快取並提供離線功能。
Comments
Post a Comment