SQLite 入門
「以 Kotlin 開發 Android 應用程式」課程假設你已熟悉下列主題:
- 資料庫的一般知識
- 尤其是 SQL 資料庫
- 用來與資料庫互動的 SQL 語言
這個頁面提供複習和快速參考指南。
SQL 資料庫
SQL 資料庫會將資料儲存在由資料列和資料欄組成的資料表中:
- 資料列和資料欄的交集處稱為欄位。
- 欄位包含資料、對其他欄位的參照,或對其他資料表的參照。
- 每一個資料列都包含一個實體。實體是透過一組專屬 ID 來識別,通常會用來當做主鍵。
- 每個資料欄透過每個資料表中的唯一名稱來識別。
SQLite
SQLite 實作的 SQL 資料庫引擎具有下列特性:
- 獨立存在 (不需要其他元件)
- 無伺服器 (不需伺服器後端)
- 無須設定 (不必為應用程式進行設定)
- 交易性 (SQLite 單一交易中的異動可能全面發生或完全不發生)
SQLite 是全球部署最廣泛的資料庫引擎。SQLite 的原始碼位於公有領域。如要進一步瞭解 SQLite 資料庫,請參閱 SQLite 網站。
範例資料表
- 名為
DATABASE_NAME
的資料庫 - 名為
WORD_LIST_TABLE
的資料表 _id
、word
和definition
的資料欄
插入 alpha
和 beta
這兩個字詞後 (其中 alpha
有兩個定義),資料表可能如下所示:
DATABASE_NAME
WORD_LIST_TABLE | ||
_id |
word |
definition |
1 |
"alpha" |
"first letter" |
2 |
"beta" |
"second letter" |
3 |
"alpha" |
"particle" |
如要尋找特定資料列中的資料,請使用 _id
或指定限制條件來設定查詢,以便從資料表選取資料列,進而完成資料列擷取作業。
交易
「交易」是指作為單一邏輯作業單元執行的一系列作業。如要符合交易資格,邏輯作業單元必須具備四個屬性:原子性、一致性、隔離性和耐用性 (ACID):
- 原子性。全面執行交易的所有資料修改作業,或是完全不執行任何修改作業。即使程式停止運作、作業系統當機或電源故障,導致將變更寫入磁碟的動作中斷,原子性也會維持不變。
- 一致性。交易完成後,交易必須讓所有資料維持一致狀態。
- 隔離性。並行交易所做的修改必須與其他並行交易所做的修改隔離。交易可辨識資料受到另一個並行交易修改前的狀態,或者交易可在第二筆交易完成後辨識資料。交易無法辨識中間狀態。
- 耐用性。交易完成後,相關效果會在系統中永久生效。即使發生系統故障,修改作業仍會持續。
交易範例:
- 從儲蓄帳戶轉帳至支票帳戶。
- 將字詞和定義輸入到字典中。
- 將變更清單提交至主要分支版本。
如要進一步瞭解交易,請參閱 Atomic Commit In SQLite (SQLite 完整確認)。
查詢語言
你需要使用 SQL 查詢語言來與資料庫互動。查詢可能相當複雜,但有如下四種基本作業:
- 插入資料列
- 刪除資料列
- 更新資料列中的值
- 擷取符合特定條件的資料列
在 Android 上,資料存取物件 (DAO) 提供插入、刪除及更新資料庫的簡便方法。如需查詢語言的完整說明,請參閱 SQL As Understood By SQLite (SQLite 所理解的 SQL)。
查詢結構
SQL 查詢具有非常完整的結構。查詢範例:
SELECT word, definition FROM WORD_LIST_TABLE WHERE word="alpha"
查詢範例的一般版本:
SELECT
資料欄FROM
資料表WHERE
資料欄="值"
查詢範例的組成部分:
SELECT
資料欄:選取要傳回的資料欄。使用*
傳回所有資料欄。FROM
資料表:指定要從中取得結果的資料表。WHERE
:位於條件之前且必須符合的選用關鍵字,例如 資料欄="值"。常見的運算子包括=
、LIKE
、<
和>
。如要連結多個條件,請使用AND
或OR
。
查詢的其他部分:
ORDER BY
:依據資料欄為結果排序的選用關鍵詞組。指定ASC
表示遞增,DESC
表示遞減。如果你未指定順序,結果就會依照預設順序顯示 (可能是有序或無序)。LIMIT
:可指定有限數量結果的關鍵字。
查詢和結果範例
下列查詢會使用先前定義的資料表:
SELECT * FROM WORD_LIST_TABLE |
取得 WORD_LIST_TABLE 資料表中的所有資料列。 |
SELECT word, definition FROM WORD_LIST_TABLE WHERE _id > 2 | 選取 id 大於 2 的所有項目的 word 和 definition 資料欄。傳回 [["alpha", "particle"]] |
SELECT _id FROM WORD_LIST_TABLE WHERE word="alpha" AND definition LIKE "%art%" |
傳回定義中包含子字串 art 的 alpha 字詞的 id 。[["3"]] |
SELECT definition FROM WORD_LIST_TABLE ORDER BY word DESC LIMIT 1 |
選取所有定義。反向排序,並在清單排序後取得第一個資料列。排序依據為指定的 word 資料欄。請注意,我們可以依照未傳回的資料欄排序![["second letter"]] |
SELECT * FROM WORD_LIST_TABLE LIMIT 2,1 |
從位置 2 開始傳回 1 個項目。位置計數從 1 開始 (不是零!)。傳回 [["2", "beta", "second letter"]] |
如要練習建立及查詢資料庫,你可以前往這個 SQL Fiddle 網站。
Android SQLite 的查詢
你可以將查詢傳送至 Android 系統的 SQLite 資料庫,做為原始查詢或參數。
rawQuery(String
sql, String[] selectionArgs)
方法會執行所提供的 SQL。這個方法會傳回結果集的 Cursor
。下表會顯示上述前兩個查詢範例當做原始查詢的樣貌:
1 |
String query = "SELECT * FROM WORD_LIST_TABLE"; |
2 |
query = "SELECT word, definition FROM WORD_LIST_TABLE WHERE _id> ? "; |
query(String
table, String[] columns, String selection, String[] selectionArgs, String
groupBy, String having, String orderBy, String limit)
方法會查詢指定資料表。這個方法會透過結果集傳回 Cursor
。以下查詢說明了如何填入引數:
SELECT * FROM WORD_LIST_TABLE |
查詢傳回的結果如下:
[["alpha", "particle"]] |
可使用的引數範例如下:
String table = "WORD_LIST_TABLE" |
注意:在實際的程式碼中,你無法為 null
值建立變數。如要瞭解這個方法的不同參數版本,請參閱 Android SQLiteDatabase
說明文件。
游標
游標是指向結構化資料列的指標。你可以將游標視為指向資料表中資料列的指標。
查詢會傳回一個指向查詢結果中第一個元素的 Cursor
物件。Cursor
類別提供在查詢結果中移動游標的方法,以及從結果中每個資料列的資料欄取得資料的方法。
當方法傳回 Cursor
物件時,你可以疊代結果、擷取資料、運用資料執行操作,然後關閉游標來釋出記憶體。
瞭解詳情
- SQLite 網站
- SQLite 所理解的 SQL 完整說明
SQLiteDatabase
classCursor
class