2015年12月24日 星期四

Android - Ch7 SQLite 資料庫建立與操作、測試工具 Stetho

 

2015平安夜獻上小品之作 : Android SQLite 資料庫,祝福大家平安喜樂,成為Programming大魔法師,阿門XD




一、SQLite 資料庫


Android系統內建「SQLite」資料庫,它是一個開放的小型資料庫,跟一般資料庫用法差不多,建立資料庫表格使用SQL的「CREATE TABLE」指令,表格欄位可以儲存的資料型態:

  • INTEGER – 整數,對應Java 的byte、short、int 和long。
  • REAL – 小數,對應Java 的float 和double。
  • TEXT – 字串,對應Java 的String。

這一節會介紹建立資料庫與表格新增、修改、刪除與查詢的基本資料庫操作。



1. 建立資料庫與表格 : SQLiteOpenHelper 類別


SQLiteOpenHelper需要建立建構子、onCreate() 及 onUpgrade()。

一個SQLite表格建議一定要包含一個可以自動為資料編號的欄位,欄位名稱固定為「_id」,型態為「INTEGER」,後面加上「PRIMARY KEY AUTOINCREMENT」的設定,就可以讓SQLite自動為每一筆資料編號以後儲存在這個欄位。

SQLiteOpenHelper 類別的相關方法 (在要操作資料庫時會用到)

  • getReadableDatabase() 建立或開啟(若存在)一個唯獨資料庫,成功則傳回 SQLiteDatabase 
  • getWritableDatabase() 建立或開啟(若存在)一個讀寫資料庫,成功開啟傳回 SQLiteDatabase 
  • close() 關閉開啟的資料庫

下面是 SQLiteOpenHelper class 撰寫的範例 : 

package com.example.opengate.lesson_map;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBService  extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 4;
    private static final String DATABASE_NAME = "temp.db";

    public DBService(Context context ) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String CREATE_TABLE = "CREATE TABLE " + ItemGPS.DATABASE_TABLE  + "("
                + ItemGPS.KEY_SR  + " INTEGER PRIMARY KEY AUTOINCREMENT ,"
                + ItemGPS.KEY_ID + " TEXT, "
                + ItemGPS.KEY_NAME + " TEXT, "
                + ItemGPS.KEY_LAT + " REAL, "
                + ItemGPS.KEY_LON + " REAL, "
                + ItemGPS.KEY_TIME + " TEXT, "
                + ItemGPS.KEY_OWNER + " TEXT, "
                + ItemGPS.KEY_INFO + " TEXT )";

        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed, all data will be gone
        db.execSQL("DROP TABLE IF EXISTS " + ItemGPS.DATABASE_TABLE);
        // Create tables again
        onCreate(db);
    }
}



2. 操作資料庫 : 用 SQLiteDatabase 類別


為了code的美觀和維護性,把執行資料庫工作的部份寫在一個獨立的Java類別中,欄位的定義也隔成一個class。

而類別中實作的函式大抵流程都差不多 :

  • dbHelper.getWritableDatabase()開啟資料庫
  • db.insert()、db.update()等方法操作資料庫
  • db.close()關閉資料庫

廢話不多說,直接看code~

DBGetdata.java

package com.example.opengate.lesson_map;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.HashMap;

public class DBGetData{
    
    private DBService dbService;
    public DBGetData(Context context) {
        dbService = new DBService(context);
    }

    public int insert(ItemGPS ItemGPS) {

        SQLiteDatabase db = dbService.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(ItemGPS.KEY_SR, ItemGPS.sr);
        values.put(ItemGPS.KEY_ID, ItemGPS.uid);
        values.put(ItemGPS.KEY_NAME, ItemGPS.name);
        values.put(ItemGPS.KEY_LAT, ItemGPS.lat);
        values.put(ItemGPS.KEY_LON, ItemGPS.lon);
        values.put(ItemGPS.KEY_TIME, ItemGPS.time);
        values.put(ItemGPS.KEY_OWNER, ItemGPS.owner);
        values.put(ItemGPS.KEY_INFO, ItemGPS.info);

        // Inserting Row
        long ItemGPS_Id = db.insert(ItemGPS.DATABASE_TABLE, null, values);
        db.close(); // Closing database connection
        return (int) ItemGPS_Id;
    }

    public ArrayList<HashMap<String, String>> getAll() {
        SQLiteDatabase db = dbService.getReadableDatabase();
        String selectQuery =  "SELECT  " +
                ItemGPS.KEY_SR + "," +
                ItemGPS.KEY_ID + "," +
                ItemGPS.KEY_NAME + "," +
                ItemGPS.KEY_LAT + "," +
                ItemGPS.KEY_LON + "," +
                ItemGPS.KEY_TIME + "," +
                ItemGPS.KEY_OWNER + "," +
                ItemGPS.KEY_INFO +
                " FROM " + ItemGPS.DATABASE_TABLE;
        
        ArrayList<HashMap<String, String>> ItemGPSList = new ArrayList<>();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if (cursor.moveToFirst()) {
            do {
                HashMap<String, String> checkpoint = new HashMap<>();
                checkpoint.put("name", cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_NAME)));
                checkpoint.put("id",cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_ID)));
                checkpoint.put("time",cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_TIME)));
                checkpoint.put("owner",cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_OWNER)));
                checkpoint.put("lan", cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_LAT)));
                checkpoint.put("lon", cursor.getString(cursor.getColumnIndex(ItemGPS.KEY_LON)));
                ItemGPSList.add(checkpoint);
            } while (cursor.moveToNext());
        }

        cursor.close();
        db.close();
        return ItemGPSList;
    }
}


ItemGPS.java

package com.example.opengate.lesson_map;

public class ItemGPS {

        // Labels DB
        public  static final String DATABASE_TABLE = "GPS_TABLE";

        // Labels Table Columns names
        public  static final String KEY_SR = "SR";
        public  static final String KEY_ID = "UID";
        public  static final String KEY_NAME = "NAME";
        public  static final String KEY_LAT = "LAT";
        public  static final String KEY_LON = "LON";
        public  static final String KEY_TIME = "TIME";
        public  static final String KEY_OWNER = "OWNER";
        public  static final String KEY_INFO = "INFO";

        public int sr;
        public String uid;
        public String name;
        public double lat;
        public double lon;
        public String time;
        public String owner;
        public String info;
}




二、瀏覽資料庫工具 Stetho


Facebook開源了一個工具Stetho,可以用Chrome測試Android的許多功能,當然也支援Android的資料庫設計。只要打開Chrome,輸入 chrome://inspect 就可以用stetho進行app測試,非常方便!




設定方式 :

首先Gradle進行dependency

dependencies {
  compile 'com.facebook.stetho:stetho:1.0.1'
}

然後在你的 App 的 Application class 進行配置 (Application class 是 App全域變數所在地,通常要自己新開一個class)

public class MyApplication extends Application {
  public void onCreate() {
    super.onCreate();
    Stetho.initialize(
      Stetho.newInitializerBuilder(this)
        .enableDumpapp(
            Stetho.defaultDumperPluginsProvider(this))
        .enableWebKitInspector(
            Stetho.defaultInspectorModulesProvider(this))
        .build());
  }
}






References


Android Tutorial 第三堂(3)Android 內建的 SQLite 資料庫http://www.codedata.com.tw/mobile/android-tutorial-the-3rd-class-3-sqlite

[Android 學習筆記] SQL 與 SQLite 資料庫教學 II
http://blog.kdchang.cc/2015/07/android-note-sql-sqlite-ii.html

Stetho
http://facebook.github.io/stetho/

使用Chrome来调试你的Android App
http://www.stormzhang.com/android/2015/03/05/android-debug-use-chrome/

Android學習_建立程式內(application)的全域變數(Global Variable)
http://wangshifuola.blogspot.tw/2011/12/androidapplicationglobal-variable.html






技術提供:Blogger.