android中的數(shù)據(jù)庫操作android中的應(yīng)用開發(fā)很難避免不去使用數(shù)據(jù)庫,這次就和大家聊聊android中的數(shù)據(jù)庫操作。
一、android內(nèi)的數(shù)據(jù)庫的基礎(chǔ)知識介紹
1.用了什么數(shù)據(jù)庫 android中采用的數(shù)據(jù)庫是SQLite這個輕量級的嵌入式開源數(shù)據(jù)庫,它是用c語言構(gòu)建的。相關(guān)簡介可以從鏈接查看。
2.數(shù)據(jù)庫基本知識觀花 對于一些和我一樣還沒有真正系統(tǒng)學(xué)習(xí)數(shù)據(jù)庫技術(shù)的同學(xué)來說,把SQL92標(biāo)準(zhǔn)中的一些基本概念、基本語句快速的了解一下,是很有必要的,這樣待會用Android的database相關(guān)方法去執(zhí)行一些數(shù)據(jù)庫語句時就不會茫然了。
①數(shù)據(jù)庫的基本結(jié)構(gòu)——表格
表格是數(shù)據(jù)庫中儲存資料的基本架構(gòu)。表格被分為欄位 (column) 及列位 (row)。每一列代表一筆資料,而每一欄代表一筆資料的一部份。舉例來說,如果我們有一個記載顧客資料的表格,那欄位就有可能包括姓、名、地址、城市、 國家、生日...等等。每一個表格擁有一個獨(dú)一無二的名字(Table Name)以便能夠讓用戶定位到它上面。一個典型的表格結(jié)構(gòu)如下:
Store_Information 表格
②關(guān)于數(shù)據(jù)類型
和其他的數(shù)據(jù)庫不同的是,sqlite是無類型的。也就是當(dāng)你創(chuàng)建一個表格時,無需對每一個欄位要存儲的數(shù)據(jù)的類型進(jìn)行聲明,當(dāng)你在給表格增加數(shù)據(jù)條目時,sqlite會自動找到存入的數(shù)據(jù)的類型。
SQLite允許忽略數(shù)據(jù)類型,但是,仍然建議在Create Table語句中指定數(shù)據(jù)類型,因?yàn)閿?shù)據(jù)類型有利于增強(qiáng)程序的可讀性。SQLite支持常見的數(shù)據(jù)類型,如VARCHAR、NVARCHAR、TEXT、 INTEGER、FLOAT、BOOLEAN、CLOB、BLOB、TIMESTAMP、NUMERIC、VARYING、CHARACTER、 NATl0NAI, VARYINGCHARACTER。這些數(shù)據(jù)類型都是SQL92標(biāo)準(zhǔn)中規(guī)定的標(biāo)準(zhǔn)數(shù)據(jù)庫數(shù)據(jù)類型,想要有更近一步了解,請參看下表。
你或許已經(jīng)在納悶了,為什么之前的數(shù)據(jù)類型是大寫的,而到了這個表格就變成了小寫的。其實(shí)這是sqlite的一個不得不提的特性:sqlite是大小寫不敏感的!這一特性對于很多c語言fans來說是很不習(xí)慣的。
③數(shù)據(jù)庫的基本操作語句
其實(shí)這個還是SQL92標(biāo)準(zhǔn)中的一部分,只是不同的數(shù)據(jù)庫會有一點(diǎn)點(diǎn)的不同而已,下面就對在android中最常用的幾個操作語句給以概述,詳細(xì)介紹請參看SQL語句簡單介紹。
(1)CREATE TABLE 由于創(chuàng)建一個表格,基本使用語法結(jié)構(gòu)是: CREATE TABLE "表格名" ("欄位1" 保存資料類型 , "欄位3" 保存資料類型 , "欄位2" 保存資料類型 .....); 例如我要創(chuàng)建剛才的Store_Information表格,就可以這樣: CREATE TABLE Store_Information (Store_Name char[50] , Sales long , Date date ); 需要提示的是,這里還是聲明了數(shù)據(jù)類型。而且不難發(fā)現(xiàn),c語言構(gòu)建的sqlite自身也有一些c語言的性格(例如一個完整語句后的分號)。
(2)SELECT 用于將資料從數(shù)據(jù)庫中的表格內(nèi)選出,基本語法結(jié)構(gòu)為: SELECT "欄位名" FROM "表格名" ; 例如我想將 Store_Information 里面的store_name 選出,則可以這樣: SELECT store_name FROM Store_Information ;
這句執(zhí)行后就會顯示如下的信息:
好了,效果一目了然。 (3)SELECT語句可以添加條件來縮小選擇結(jié)果: 去掉重復(fù)的結(jié)果: SELECT DISTINCT "欄位名" FROM "表格名"
例如將剛才的語句改為:
SELECT DISTINCT store_name FROM Store_Information ;
則顯示的結(jié)果為:
實(shí)現(xiàn)有條件的篩選:
SELECT "欄位名" FROM "表格名" WHERE "條件語句" ;
條件語句和c語言中的類似,只不過用AND表示“且”,OR表示“或”。
例如對表執(zhí)行如下語句:
SELECT store_name FROM Store_Information WHERE Sales > 1000 ;
則顯示結(jié)果為: store_name Los Angeles
其中WHERE語句用的較多,因?yàn)樗梢詫?shí)現(xiàn)自定義條件的使用和多條件的組合。
(4)INSERT INTO
在表格中加入資料——可以實(shí)現(xiàn)一筆的加入和多筆的加入。
加入一筆: INSERT INTO "表格名" ("欄位1", "欄位2", ...) VALUES ("值1", "值2", ...); 加入多筆: INSERT INTO "待加入數(shù)據(jù)的表格" ("欄位1", "欄位2", ...) SELECT "欄位3", "欄位4", ... FROM "被加入的表格" ;
加入多筆其實(shí)就是將另一個表格加入到現(xiàn)有表格中。
(5)UPDATE
用于修改表格中的數(shù)據(jù),語法結(jié)構(gòu)為:
UPDATE "表格名" SET "欄位1" = [新值] WHERE {條件};
例如:
UPDATE Store_Information SET Sales = 500 WHERE store_name = "Los Angeles" AND Date = "Jan-08-1999" ;
具體是什么意思的話就不說了,你懂的~~~
(6)DELETE FROM
刪除表格中的某些數(shù)據(jù),語法結(jié)構(gòu)為:
DELETE FROM "表格名" WHERE {條件} ;
滿足條件的所有資料都會被刪除掉。
二、如何在android中調(diào)用數(shù)據(jù)庫資源 在android中主要有兩種方法來實(shí)現(xiàn)對數(shù)據(jù)庫的訪問,一種是adb shell方式,另一種是通過相關(guān)的android 的java類來間接的對數(shù)據(jù)庫來進(jìn)行操作。其中前者主要用于在開發(fā)過程中進(jìn)行調(diào)試等工作,后者則為android中主要的使用數(shù)據(jù)庫的方式。 下面就對這兩種方式進(jìn)行一個簡要的介紹。
1.adb shell方式
說白了,adb shell 就是一個android模擬器的后臺資源調(diào)用器(個人理解啦~~)。它的操作方式和命令提示符差不多——以命令行的方式進(jìn)行。
既然是模擬器的后臺資源調(diào)用器,那當(dāng)然得先打開android模擬器了。
打開模擬器后,再打開命令提示符,在里面輸入adb shell,這時會出現(xiàn)一個#號(懂linux的同學(xué)懂的),具體效果如下:
然后你就可以像在linux下進(jìn)行shell命令的執(zhí)行了。
接著輸入 cd data/data/ 并執(zhí)行,再執(zhí)行l(wèi)s,則會顯示一些安裝的軟件的工程包名,效果如下:
其實(shí)這在模擬器中是以一個個文件夾的形式存在的,所以你可以用cd命令進(jìn)入它。例如我進(jìn)入一個后,再用ls命令顯示里面的內(nèi)容:
該文件夾內(nèi)又存在databases、 lib等文件夾(如果沒有databases的話可以自己手動用mkdir命令創(chuàng)建一個)。而這個databases文件夾就是這個應(yīng)用的數(shù)據(jù)庫文件的所 在地,cd進(jìn)入后,應(yīng)該會看到里面有一個或多個.db格式的文件(其實(shí)sqlite對文件的名字沒有特殊要求,你用.txt等其他的格式也可以,但推 薦.db)。如果沒有db文件的話,可以用如下命令創(chuàng)建:sqlite3 mydata.db。這樣就會在databases里面生成了一個數(shù)據(jù)庫文件。如果已存在,可以直接用sqlite3命令調(diào)用該數(shù)據(jù)庫文件,命令為 sqlite3 mydata.db(其實(shí)就是和剛才的命令一個樣)。接下來你就會看到:
在sqlite>后面就可以執(zhí)行你的sql語句了。下面執(zhí)行了一些簡單的語句:
好了,adb shell的方式介紹到這里。 2.通過android中的相關(guān)java類
Android中對數(shù)據(jù)庫進(jìn)行操作的相關(guān)的借口、類等都在andorid.database和android.database.sqlite兩個包里 面。里面存在著很多的與數(shù)據(jù)庫操作相關(guān)的類,但是在平時普通的開發(fā)中最經(jīng)常遇到的僅僅就是那幾個類而已,所以在這里我就省去通篇的介紹,對一些常用的接 口、類做一下簡介。
①SQLiteDatabase(android.database.sqlite.SQLiteDatabase)
文檔信息: public class SQLiteDatabase
Exposes methods to manage a SQLite database.SQLiteDatabase has methods to create, delete, execute SQLcommands, and perform other common database management tasks.atabase names must be unique within an application, not across all applications.
簡介: 這個是在android中數(shù)據(jù)庫操作使用最頻繁的一個類。通過它可以實(shí)現(xiàn)數(shù)據(jù)庫的創(chuàng)建或打開、創(chuàng)建表、插入數(shù)據(jù)、刪除數(shù)據(jù)、查詢數(shù)據(jù)、修改數(shù)據(jù)等操作。
重要方法介紹:
(1)public static SQLiteDatabase openOrCreateDatabase (File file, SQLiteDatabase.CursorFactory factory) public static SQLiteDatabase openOrCreateDatabase (String path, SQLiteDatabase.CursorFactory factory) 這個方法用于打開或創(chuàng)建一個數(shù)據(jù)庫(對于sqlite來說,就是打開或產(chǎn)生一個數(shù)據(jù)庫文件),參數(shù)中的File類就是java中表示系統(tǒng)文件路徑的File類,而SQLiteDatabase.CursorFactory則是一個產(chǎn)生Cursor對象的工廠類(Cursor接口將在后面介紹到)。 (2)public long insert (String table, String nullColumnHack, ContentValues values) 看到它的名字以及sql中的相關(guān)語句你不難猜到這個方法用于在數(shù)據(jù)庫中加入數(shù)據(jù)。ContentValue類似于java中HashMap類,用于以鍵值對的方式保存數(shù)據(jù)。 (3)public int delete (String table, String whereClause, String[] whereArgs) 不用說了,用于刪除表中的數(shù)據(jù)。 (4)public Cursor query (booleandistinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) 名字很長是吧,它的功能也很強(qiáng)大,用于查詢數(shù)據(jù)庫中的數(shù)據(jù)。 (5)public int update (String table, ContentValues values, String whereClause, String[] whereArgs) 用于修改數(shù)據(jù)。根據(jù)傳入?yún)?shù)的名字可以對使用方法略知一二。 (6)public void execSQL (String sql, Object[] bindArgs) public void execSQL (String sql) 這是我個人認(rèn)為最為重要的方法。這個方法用于執(zhí)行你用String表示的非查詢(因?yàn)樗粫祷匾粋€Cursor對象)的sql語句,例如CREATE,SELECT等。遺憾的是現(xiàn)在尚無法一次調(diào)用該方法來執(zhí)行用“;”分開的多條sql語句。第二個重寫方法使用的更多些。 另外在此提問:第一個重寫方法中bindArgs表示的是一些什么,用來做什么用,知道的同學(xué)可以告訴我下,謝謝! (7)public void close () 用來關(guān)閉數(shù)據(jù)庫并釋放數(shù)據(jù)庫占用的相關(guān)資源。
②SQLiteOpenHelper (android.database.sqlite.SQLiteOpenHelper)
文檔信息: public abstract class SQLiteOpenHelperA helper class to manage database creation and version management. You create a subclass implementing
簡介: 正如它的名字所表述的一樣,這個抽象類是一個輔助類(Helper),用來打開(若數(shù)據(jù)庫已存在)或創(chuàng)建數(shù)據(jù)庫的。關(guān)于抽象類我們都知道,如果要使用它,一定是繼承它。所以使用它都是通過自己定義一個類繼承于它,并實(shí)現(xiàn) 在我看來,所謂的輔助類,其實(shí)就是充當(dāng)了一個封裝器——也就是說用于對其輔助的類實(shí)現(xiàn)一個java上的封裝。在這里,SQLiteOpenHelper就是用來對SQLiteDatabase進(jìn)行一個封裝處理。初學(xué)的同學(xué)想要進(jìn)一步理解的話可以先看看什么是封裝。
它包含的方法如下:
(1)synchronized void close() 關(guān)閉任何已開啟的數(shù)據(jù)庫對象。 (2)synchronized SQLiteDatabase getReadableDatabase() 創(chuàng)建或打開一個僅僅可讀的(read-only)數(shù)據(jù)庫。 (3)synchronized SQLiteDatabase getWritableDatabase() 創(chuàng)建或打開一個可讀可寫的數(shù)據(jù)庫。
(4)abstract void onCreate(SQLiteDatabase db)
當(dāng)數(shù)據(jù)庫被第一次創(chuàng)建時被調(diào)用的的方法(類似于Activity的onCreate())。
(5)void onOpen(SQLiteDatabase db)
數(shù)據(jù)庫已經(jīng)被成打開后被調(diào)用。
(6)abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
當(dāng)數(shù)據(jù)庫需要被更改(更新)時被調(diào)用。
③Cursor(android.database.Cursor)
文檔信息: public interface CursorThis interface provides random read-write access to the result set returned by a database query.
簡介: Cursor沒有構(gòu)造方法,只能通過query方法獲得。 前面提到了,execSQL方法無法執(zhí)行與查詢相關(guān)的sql語句,是因?yàn)闊o法返回一個Cursor對象——查詢需要將查到的結(jié)果(就是表中的哪一行滿足查詢條件)返回,execSQL是返回void的,所以無法操作查詢語句。從這里可以了解到,Cursor接口從某種意義上說就是為了彌補(bǔ)這一點(diǎn)的——query方法就是返回了一個Cursor對象。從名字上看,它的意思是游標(biāo),所以大概可以猜到他起到了一個指代的作用(事實(shí)上就是的,它指代數(shù)據(jù)庫中保存數(shù)據(jù)的表的一行,并且還可以簡單的處理該行數(shù)據(jù)項(xiàng)的信息)。從類的描述看,Cursor提供了對一個數(shù)據(jù)庫查詢動作返回結(jié)果束的隨機(jī)讀寫途徑,也就是說,它是一個對查詢操作返回結(jié)果進(jìn)行進(jìn)一步處理的類,而這些處理就是用Cursor里的方法實(shí)現(xiàn)的。 結(jié)合SimpleCursorAdapter這個適配器類,你可以很方便的將數(shù)據(jù)庫中的數(shù)據(jù)顯示到AdapterView(例如ListView,GridView)中——這也是Cursor的另一大用處。 如果你了解java中的迭代器(Iterator)的話你就會發(fā)現(xiàn)其實(shí)Cursor和迭代器有些相似,這樣你可能會更快的了解Cursor。
一些常用的方法有: (1)public abstract boolean moveToPosition (int position) public abstract boolean moveToFirst () public abstract boolean moveToLast () public abstract boolean moveToNext () public abstract boolean moveToPrevious () 把這些方法放在一起的目的很明顯:它們都是對Cursor指向的位置進(jìn)行操作的方法——移到某個指定的位置、移到第一行、移到最后一行、移向下一行、移向上一行等等。
(2)public abstract int getCount () 返回Cursor指向的表含有的總數(shù)據(jù)項(xiàng)數(shù)。
(3)public abstract boolean requery () Cursor是被一個query方法產(chǎn)生的,而這個方法就是將那個query方法所做的查詢動作再執(zhí)行一遍——這將會改變調(diào)用該方法的Cursor對象的值,也就是說,Cursor使用了該方法后就復(fù)位了。
(4)public abstract boolean isClosed () public abstract boolean isFirst () public abstract boolean isLast () public abstract boolean isNull (int columnIndex) public abstract boolean isClosed () public abstract boolean isAfterLast () public abstract boolean isBeforeFirst () 在java中,類似于isWhatever形式的方法大都是對對象狀態(tài)進(jìn)行判斷的方法——Whatever成立則返回true,不成立則返回false。這些方法也不例外。 值得提一下的是isNull方法,該方法測試某個欄位所保存的信息是否為NULL。參數(shù)columnIndex代表了那個欄位的代號。
④另外建議各位了解一下SimpleCursorAdapter(android.widget.SimpleCursorAdapter)這個適配器類。
好了,介紹這么多了,該上源碼了。這個源碼很簡單,但代表一種使用模式,所以還是值得仔細(xì)研究的。
1.實(shí)現(xiàn)一個繼承SQLiteOpenHelper的類
2.創(chuàng)建一個錄入數(shù)據(jù)的類
3.創(chuàng)建一個顯示數(shù)據(jù)庫數(shù)據(jù)的類
在這些代碼中,關(guān)鍵理解第一個的思想以及形式即可,其他都是基于它進(jìn)行的一些操作而已。另外布局的代碼就不加了,沒啥技術(shù)含量。 |
|
|