1. 程式人生 > >Android學習之基礎知識九 — 資料儲存(持久化技術)之SQLite資料庫儲存

Android學習之基礎知識九 — 資料儲存(持久化技術)之SQLite資料庫儲存

  前面一講介紹了資料持久化技術的前兩種:檔案儲存、SharedPreferences儲存。下面介紹第三種技術:SQLite資料庫儲存

一、SQLite資料庫儲存

  SQLite資料庫是一款輕量級的關係型資料庫,它的運算速度非常快,佔用資源很少,通常只需要幾百KB的記憶體就足夠了,因而特別適合在移動裝置上使用。SQLite不僅支援標準的SQL語法,還遵循了資料庫的ACID事務,所以只要你以前使用過其他的關係型資料庫,就能很快上手。而SQLite又比一般的資料庫要簡單的得多,它甚至不用設定使用者名稱和密碼就可以使用。Android正是把這個功能極為強大的資料庫嵌入到了系統當中,成為了Android系統的內建資料庫,使得本地持久化的功能有了一次質的飛躍。

  前面我們所學的檔案儲存和SharedPreferences儲存畢竟只適用於儲存一些簡單的資料和鍵值對,當需要儲存大量複雜的關係型資料的時候,這兩種儲存方式就很難應付了,這時候就需要使用到SQLite資料庫。

1.1、建立資料庫(SQLiteOpenHelper幫助類)

  Android為了讓我們更加方便地管理資料庫,專門提供了一個SQLiteOpenHelper幫助類,藉助這個類我們可以非常簡單的對資料庫進行建立和升級。下面就來介紹一下SQLiteOpenHelper的基本用法。

  1、首先需要知道SQLiteOpenHelper是一個抽象類,這意味著如果我們想要使用它的話,就需要建立一個自己的幫助類去繼承它,SQLiteOpenHelper中有兩個抽象方法,分別是:onCreate()方法和 onUpgrade()

方法,我們必須在自己的幫助類中重寫這兩個方法,然後分別在這兩個方法中去實現建立、升級資料庫的邏輯。

  2、SQLiteOpenHelper中還有兩個非常重要的例項方法:getReadableDatabase()和getWritableDatabase()。這兩個方法都可以建立或開啟一個現有的資料庫(如果資料庫已經存在則直接開啟,否則建立一個新的資料庫),並返回一個對資料庫進行讀寫操作的物件,不同的是,當資料庫不可寫入的時候(如磁碟空間已滿),getReadableDatabase()方法返回的物件將以只讀的方式去開啟資料庫,而getWritableDatabase()方法則將出現異常。

  3、SQLiteOpenHelper中有兩個構造方法可供重寫,一般使用引數少一點的那個構造方法即可。這個構造方法中接收4個引數,第一個引數是Context,這個沒什麼好說的,必須要有它才能對資料庫進行操作;第二個引數是資料庫名,建立資料庫時使用的就是這裡指定的名稱;第三個引數允許我們在查詢資料的時候返回一個自定義的Cursor,一般都是傳入null;第四個引數表示當前資料庫的版本號,可用於對資料庫進行升級操作。構建出SQLiteOpenHelper的例項後,再呼叫它的:getReadableDatabase()或getWritableDatabase()方法就能建立資料庫了,資料庫檔案會存放在:/data/data/程式包名/databases/目錄下。此時,重寫的onCreate()方法也會得到執行,所以通常會在這裡去處理一些建立表的邏輯。

接下來我們就通過實際的例子來直觀的體會一下SQLiteOpenHelper的用法吧。

  這裡我們希望建立一個名為BookStore.db的資料庫,然後在這個資料庫中新建一張Book表,表中有id(主鍵)、作者、價格、頁數和書名等列,建立資料庫表當然還是需要用建表語句的,Book表的建表語句如下所示:

  SQLite不像其他資料庫擁有眾多複雜的資料型別,它的資料型別很簡單,integer表示整型,real表示浮點型,text表示文字型別,blob表示二進位制型別。另外我們還使用了primary key將id設定為主鍵,並用autoincrement關鍵字表示id列是自增長的。

然後我們開始寫程式碼:

第一步:新建MyDatabaseHelper類繼承SQLiteOpenHelper

第二步:設定一個按鈕,用於實現點選按鈕建立資料庫和建表的功能

第三步:在MainActivity中實現資料庫和表的建立

第四步:執行程式,點選按鈕,彈出一個建立成功的Toast提示,說明資料庫和表我們都已經建立完成了。

資料庫和表都建立完成後,我們知道它是儲存在:/data/data/com.workspace.hh.databasetest/databases目錄下,如果還是使用File Explorer開啟,我們只會看到一個BookStore.db檔案,看不到Book表,這裡我們換一個開啟方式來檢視資料庫和Book表,就是使用adb shell來對資料庫和表的建立情況進行檢測。

  adb是Android SDK中自帶的一個除錯工具,使用這個工具可以直接對連線在電腦上的手機或模擬器進行除錯操作,它存放在sdk的platform-tools目錄下,如果想要在命令列中使用這個工具,就需要先把它的路徑配置到環境變數中。開啟計算機 ---> 屬性 ---> 高階系統設定 ---> 環境變數,然後在系統變數中找到Path並點選編輯,將platform-tools目錄配置進去,如圖所示:

配置完成後,就可以使用adb工具了:

  (1)開啟Android Studio中的Terminal工具:

 

  (2)輸入:adb shell,回車,進入到裝置的控制檯

  (3)使用cd命令進入到db檔案的目錄:

  (4)使用:ls命令來檢視該目錄裡的檔案:該目錄下出現了兩個資料庫檔案,一個正是我們的建立的BookStore.db,而另外一個BookStore.db-journal則是為了讓資料庫能夠支援事務而產生的臨時日誌檔案,通常情況下這個檔案的大小都是0位元組。

  (5)藉助sqlite命令來開啟資料庫:sqlite3 BookStore.db

  (6)開啟資料庫後,就可以對這個資料庫中的表進行管理了,首先我們看一下資料庫中有哪些表:(.table)

可以看到資料庫中有兩張表,android_metadata表示每個資料庫中都會自動生成的,不用管它,而另外一張book表就是我們建立的了。

 

  (7)通過(.schema)命令來檢視它們的建表語句:從建表語句中我們可以看出,資料庫和表已經建立完成了。

  (8)通過(.exit)或(.quit)命令退出資料庫的編輯,然後再通過(exit)命令退出裝置的控制檯

1.2、升級資料庫

   在上面MyDatabaseHelper中還保留了一個:onUpgrade()方法,這個方法就是用於對資料庫進行升級的,它在整個資料庫的管理工作中起著非常重要的作用。目前DatabaseTest專案中已經存在一張Book表用於存放書的各種詳細資料,接著我們再新增一張Category表用於記錄圖書的分類,Category表中有id(主鍵)、分類名個分類程式碼這幾列,建表語句如下:

現在我們開始在程式碼中進行建表:

第一步:修改MyDatabaseHelper中的程式碼:

第二步:要執行:onUpgrade()方法,只需要輸入一個比當前資料庫的版本號大的版本號就行了

第三步:執行程式,點選按鈕,我們看到有Toast提示彈出,接著我們檢查資料庫中是否成功建立了Category表,發現建表成功。

 

1.3、新增資料

   我們對資料庫的操縱無非就4種:CRUD,即:Create新增、Retrieve查詢、Update更新、Delete刪除。每一種操作都各自對應了一種SQL命令:新增用insert、查詢用select、更新用update、刪除用delete;Android提供了一系列的輔助方法,使得在Android中即使不去編寫SQL語句,也能輕鬆完成所有的CRUD操作。

  前面我們已經知道,呼叫SQLiteOpenHelper的:getReadableDatabase()或getWritableDatabase()方法是可以用於建立和升級資料庫的,不僅如此,這兩個方法還都會返回一個SQLiteDatabase物件,藉助這個物件我們就可以對資料進行CRUD操作了。

  SQLiteDatabase中提供了一個:insert()方法,這個方法就是專門用於新增資料的,它接收3個引數,第一個引數是表名,向哪個表新增資料,就是傳入哪個表的名字;第二個引數是用於在未指定新增資料的情況下給某些可為空的列自動賦值NULL,一般我們用不到這個功能,直接傳入null即可;第三個引數是一個ContentValues物件,它提供一系列的:put()方法過載,用於向ContentValues中新增資料,只需要將表中的每個列名以及相應的待新增資料傳入即可。

下面就提高例子來親自體驗一下新增資料的操作:

第一步:建立一個按鈕,通過點選按鈕來新增資料

第二步:在MainActivity中實現新增資料的操作:

 

第三步:執行程式,看到有新增資料成功的提示資訊,然後通過:(select * from book;)查詢語句檢視新增的兩條資料(注意查詢語句後面有分號

 1.4、更新資料

  SQLiteDatabase中也提供了一個非常好用的:update()方法,用於對資料進行更新,這個方法接收4個引數,第一個引數個insert()方法一樣,也是表名,指定去更新哪張表裡的資料。第二個引數是ContentValues物件,要把更新的資料在這裡組裝進去。第三、第四個引數用於約束更新某一行或某幾行中的資料,不指定的話預設就是更新所有行。

第一步:建立一個按鈕,通過點選按鈕實現資料更新

第二步:在MainActivity中實現業務邏輯

第三步:執行程式,點選按鈕,在Terminal中檢視是否更新成功

  

1.5、刪除資料

   SQLiteDatabase中提供了一個:delete()方法,專門用於刪除資料,這個方法接收三個引數,第一個引數仍然是表名,第二、三個引數又是用於約束刪除某一行或幾行的資料,不指定的話預設就是刪除所有行。

第一步:新增一個刪除按鈕,通過點選按鈕來刪除資料

第二步:在MainActivity中實現功能

第三步:執行程式,點選按鈕,然後檢視book表中的資料是否被刪除,從查詢的資料中,我們可以看出,頁數為899的“The mental of Java”這本書已經被刪除。

  

1.6、查詢資料

   SQLite的全稱是:Structured Query Language,翻譯成中文就是結構化查詢語言,它的大部分功能都體現在“查”這個字上,而“增刪改”只是其中的一小部分功能。SQLiteDatabase中還提供了一個:query()方法用於對資料進行查詢,這個方法的引數非常的複雜,最短的一個方法過載也需要傳入7個引數,這7個引數的含義是:

  第一個引數:表名,即我們希望在哪張表中查詢資料

  第二個引數:指定去哪兒查詢哪幾列,如果不指定則預設查詢所有列

  第三、四個引數:約束查詢某一行或某幾行的資料,不指定則預設查詢所有行的資料

  第五個引數:指定需要去group by的列,不指定則表示不對查詢結果進行group by操作

  第六個引數:對group by之後的資料進行進一步的過濾,不指定則表示不進行過濾

  第七個引數:指定查詢結果的排序方式,不指定則表示使用預設的排序方式。

具體的內容可參照下表:

雖然:query()方法的引數非常多,但是我們不必為每條查詢語句都指定所有的引數,多數情況下只需要傳入少數幾個引數就可以完成查詢操作了。呼叫query()方法後會返回一個Cursor物件,查詢到的所有資料都將從這個物件中取出。接下來我們就通過一個簡單的例子來體驗資料的查詢操作:

第一步:建立一個按鈕,通過點選按鈕來查詢資料

第二步:在MainActivity中實現功能邏輯

第三步:打印出查詢到資料

 

1.7、使用SQL操作資料庫

   Android提供了一系列方法可以直接通過SQL來操作資料庫,上面的CRUD操作可以用下面的SQL語句來完成:

  除了查詢語句的時候呼叫的是SQLiteDatabase的:rawQuery()方法,其他操作都是呼叫:execSQL()方法。