Android高效入門—SQLite資料庫

作者 | 2016-05-09

Android的SQLite資料庫

A4958

SQLite是一套開放原始碼的資料庫函式庫,並遵循ACID關聯式資料標準,使用標準的SQL語法,提供單機、無需連線環境的資料庫的管理系統。它被廣泛地使用在嵌入式系統、瀏覽器、作業系統內部。

Android支援SQLite資料庫,每個應用程式都可選擇建立自己的資料庫,將資料儲存在SQLite資料庫檔案中,開發人員使用Android提供的API類別庫即可在應用程式中存取資料庫中資料,包括查詢、新增、刪除與更新等標準的SQL存取語法。它亦提供應用程式訂定資料庫版本,可在新版應用程式一併進行資料庫版本的複製、轉移等工作。

一開始在Atm專案中建立一個具實感設計的活動,再進行必要的元件與畫面配置,待活動與畫面架構成形後,再進行SQLite資料庫的介紹與實作。因為,使用到資料庫的情境都需要使用者介面,筆者希望在設計操作資料庫的程式碼時,能與使用者的介面互動,並在練習過程中認識各個元件的角色與使用方法,單純地認識片段的資料庫操作程式碼,並不足以在設計應用程式時派上用場。

準備活動

建立一個新活動FinanceActivity進行範例與操作說明,這是一個簡單的記帳功能,可新增並顯示所有消費記錄,請在Atm專案中建立一個「Basic Activity」名稱為「FinanceActivity」,目的是顯示消費清單可在主畫面中按下「投資理財」功能時開啟這個活動,一開始是無任何內容,如下圖。

A4952

第二個活動是簡易的「Empty Activity」空白活動,名稱為「AddActivity」在此活動中設計新增消費記錄的使用者介面,供使用者輸入消費記錄,如下圖:

A4951

第一個消費清單為FinanceActivity,第二個新增消費為AddActivity,請先依以下步驟建立活動。

1.  建立活動

請使用功能表的「File/New/Activity/Basic Activity」建立具實感設計的基本活動,名稱為FinanceActivity,如下圖:

A4942

上述動作會產生一個FinanceActivity類別與兩個版面配置檔「activity_finance.xml」與「content_finance.xml」。

A4943

完成後,再使用功能表的「File/New/Activity/Empty Activity」新增另一個空白活動,名稱為AddActivity,如下圖:

A4944

上述動作產生一個AddActivity類別與一個版面配置檔「activity_add.xml」,如下:

A4945

2. 畫面配置

再打開產生的「res/layout/activity_add.xml」版面配置檔,加入必要的元件,預覽與元件結構如下圖:

A4946

配置檔activity_add.xml原始碼如下:

三個輸入方塊的id值為「ed_date」、「ed_info」與「ed_amount」,分別代表日期、消費說明與消費金額的輸入方塊,再為按鈕設定onClick屬性為「add」。

3, 實作必要程式碼

請再開啟AddActivity,設計以下程式碼:

上述程式使用前面章節介紹的方法,取得畫面中三項輸入元件,並將元件設定為屬性,最後加入新增按鈕的事件處理方法「add」。

AddActivity準備完成後,請開啟FinanceActivity,修改原本「onCreate」方法內浮動鈕的事件程式碼,將SnackBar產生程式碼換成

完成後,按下浮動鈕將開啟AddActivity活動畫面。

最後為了能在主功能畫面中按下「投資理財」功能時,可啟動FinanceActivity活動,請在MainActivity的onItemClick方法內的switch…case敍述中加入:

SQLiteOpenHelper類別

存取資料庫需要瞭解對檔案格式、協定與規範,以程式實作這些功能更是複雜,請不用擔心,Android提供一個已經實作好的-SQLiteOpenHelper類別,它的package是android.datatbase.sqlite。當應用程式需要使用SQLite資料庫時,只需要設計一個新類別並繼承SQLiteOpenHelper,這個類別即具有存取資料庫的能力。

建立應用程式的SQLiteOpenHelper類別

請展開專案「app/java/com.tom.atm」,在com.tom.atm套件上按右鍵選擇「New/Java Class」,名稱輸入「MyDBHelper」產生類別,再加入繼承「extends SQLiteOpenHelper」語法,如下:

A4377

1. 實作方法

由於SQLiteOpenHelper是抽象類別,其子類別必須實作必要的方法,請將游標停在出現錯誤的類別定義該行,按下「Alt+Enter」選擇「Implement methods」,如下圖:

A4378

對話框中已自動選擇onCreate與onUpgrade兩個方法,按下Enter即可,如下:

A4379

2. 實作建構子

因父類別SQLiteOpenHelper中並未實作無參數的建構子,因此MyDBHelper必須設計建構子,可將游標停在出現錯誤的類別定義該行,按下「Alt+Enter」選擇「Create constructor matching super class」建立與父類別相同參數的建構子,如下圖:

A4380

再選擇第一個即可,最後完成程式碼如下:

SQLiteDatabase類別

SQLiteDatabase類別的用途存取SQLite資料庫,提供許多能夠存取資料庫的方法,如query查詢、insert新增、update更新與關閉資料庫等方法,在這些方法中使用SQL語法並執行。

在SQLiteOpenHelper類別中可呼叫以下方法得到SQLiteDatabase物件:

  • getReadableDatabase()方法

讀取資料庫的SQLiteDatabase物件,可用在查詢。

  • getWritableDatabase()方法

擁有更新能力的SQLiteDatabase物件,用途為新增、修改或刪除。

請依實際開發時的用途,選擇呼叫上述兩個方法取得適合的SQLiteDatabase物件。

建立資料表格的時機-onCreate

當應用程式中執行到有關任何存取資料庫的指令時,假如資料庫檔案不存在,則會立即執行本方法。因此,在此撰寫建立資料庫表格的程式碼,若表格中需要初始資料時,在建立表格完成後可繼續撰寫新增資料記錄的程式碼。

在本例中每一筆消費記錄包括以下欄位:

  1. 消費日期
  2. 說明
  3. 金額

在表格中的辨識ID,請使用「_id」為欄位名稱,使其成為自動產生的主鍵(Primary key) ,表格欄位與資料型態如下表:

表格名稱:exp

欄位名稱資料型態備註
_idINTEGERPRIMARY KEY
cdateDATETIMENOT NULL
infoVARCHAR(20)
amountINTEGER

建立exp表格的SQL語法為:

在onCreate方法中,取得可寫入SQLiteDatabase物件後,呼叫execSQL方法建立exp表格,如下:

應用程式昇級-onUpgrade

當使用者手機中已安裝較舊版本應用程式時,在存取資料庫指令時自動檢查到舊的資料庫檔案時,會自動執行本方法。onUpgrade方法內可撰寫程式碼以協助更新使用者舊資料,以順利移轉至新版的資料表格。

使用SQLiteOpenHelper

完成了MyDBHelper類別設計後,請開啟AddActivity,準備設計新增消費記錄功能。

在MainActivity中的onCreate方法,呼叫MyDBHelper的建構子建立物件,物件名稱為「helper」,請將helper定義為屬性,如下:

MyDBHelper的建構子是與SQLiteOpenHelper相同的,參數與用法如下:

  1. Context context

此參數使用this關鍵字,即傳入AddActivity本身。

  1. String name

name為資料庫檔案名稱,由開發者自訂,可以使用任何副檔名,如「expense.db」或「expense.sqlite」。

  1. CursorFactory factory

在此使用null,代表以標準模式SQLiteCursor處理Cursor。

  1. int version

本應用程式目前資料庫版本,在此使用1代表第一個版本。

新增資料

使用SQLiteDatabase的insert方法新增記錄至表格,第一個參數為表格名稱,第三個則是「資料包」,使用ContentValues類別,就像是Java的Map集合類別,專門儲存Key-Value的一組對應資料組,其中Key鍵值使用欄位的名稱,Value則是該欄位的值,如下圖:

A4383

請在AddActivity的add方法中實作,將一筆消費記錄儲存在一個ContentValues物件中,最後再呼叫SQLiteDatabase的insert方法新增記錄,如下:

本文章內容擷取自[Android實作這樣學]電子書

 

專案設計到此時,大致上的功能是完成了,只是介面上還需要再改進,如日期、說明等輸入的方式。請參考延續本篇的元件使用文章:

Android的日期選擇元件DatePicker—SQLite延伸內容1

相關文章:

Category: Android SQLite 標籤:, , , , , ,

關於 Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 , 為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

14 thoughts on “Android高效入門—SQLite資料庫

  1. Morton

    老師好:
    因照著做有發現報錯,在onCreate那邊的getWritableDatabase().execSQL ,我把它改成db.execSQL才能建立,再麻煩你確認一下,謝謝~

    回覆
    1. Hank Tom 文章作者

      您好,這是個問題,應使用方法中的db物件去執行才對,這是內容的錯誤,謝謝。

      回覆
  2. yuren

    02-09 07:56:33.369 2584-2584/com.example.user.atm D/ADD: -1
    請問我的是-1是什麼意思?

    回覆
      1. 000

        請問如果都照打,但是新增失敗 怎麼辦? 要怎麼修改?

        回覆
  3. Kuang

    請問為什麼 table_name要用 main.exp? 不能直接用 exp就好了嗎

    回覆
    1. Hank Tom 文章作者

      每個DBMS都會有Database後,才有Tables,main就是SQLite中使用的預設Database名稱,有加沒加都可以

      回覆
  4. Code

    老師,我照著做 發現回傳的是-1,於是我把下面這行
    values.put(“into”, info);
    改成
    values.put(“info”, info);
    就正常了,不知道是不是內容錯誤

    回覆
  5. Soar

    老師好:
    因照著做,發現到好像多打了一個 . 在db.execSQL();這句裡面

    回覆

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *