1、使用嵌入式關係型SQLite數據庫存儲數據mysql
在Android平臺上,集成了一個嵌入式關係型數據庫——SQLite,SQLite3支持NULL、INTEGER、REAL(浮點數字)、TEXT(字符串文本)和BLOB(二進制對象)數據類型,雖然它支持的類型只有五種,但實際上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等數據類型,只不過在運算或保存時會轉成對應的五種數據類型。 SQLite最大的特色是你能夠把各類類型的數據保存到任何字段中,而不用關心字段聲明的數據類型是什麼。例如:能夠在Integer類型的字段中存放字符串,或者在布爾型字段中存放浮點數,或者在字符型字段中存放日期型值。 但有一種狀況例外:定義爲INTEGER PRIMARY KEY的字段只能存儲64位整數, 當向這種字段保存除整數之外的數據時,將會產生錯誤。 另外,在編寫CREATE TABLE 語句時,你能夠省略跟在字段名稱後面的數據類型信息,以下面語句你能夠省略name字段的類型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite能夠解析大部分標準SQL語句,如:程序員
2、使用SQLiteOpenHelper對數據庫進行版本管理web
咱們在編寫數據庫應用軟件時,須要考慮這樣的問題:由於咱們開發的軟件可能會安裝在不少用戶的手機上,若是應用使用到了SQLite數據庫,咱們必須在用戶初次使用軟件時建立出應用使用到的數據庫表結構及添加一些初始化記錄,另外在軟件升級的時候,也須要對數據表結構進行更新。那麼,咱們如何才能實如今用戶初次使用或升級軟件時自動在用戶的手機上建立出應用須要的數據庫表呢?總不能讓咱們在每一個須要安裝此軟件的手機上經過手工方式建立數據庫表吧?由於這種需求是每一個數據庫應用都要面臨的,因此在Android系統,爲咱們提供了一個名爲SQLiteOpenHelper的抽象類,必須繼承它才能使用,它是經過對數據庫版本進行管理來實現前面提出的需求。
爲了實現對數據庫版本進行管理,SQLiteOpenHelper類提供了兩個重要的方法,分別是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用於初次使用軟件時生成數據庫表,後者用於升級軟件時更新數據庫表結構。當調用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法獲取用於操做數據庫的SQLiteDatabase實例的時候,若是數據庫不存在,Android系統會自動生成一個數據庫,接着調用onCreate()方法,onCreate()方法在初次生成數據庫時纔會被調用,在onCreate()方法裏能夠生成數據庫表結構及添加一些應用使用到的初始化數據。onUpgrade()方法在數據庫的版本發生變化時會被調用,通常在軟件升級時才需改變版本號,而數據庫的版本是由程序員控制的,假設數據庫如今的版本是1,因爲業務的變動,修改了數據庫表結構,這時候就須要升級軟件,升級軟件時但願更新用戶手機裏的數據庫表結構,爲了實現這一目的,能夠把原來的數據庫版本設置爲2(有同窗問設置爲3行不行?固然能夠,若是你願意,設置爲100也行),而且在onUpgrade()方法裏面實現表結構的更新。當軟件的版本升級次數比較多,這時在onUpgrade()方法裏面能夠根據原版號和目標版本號進行判斷,而後做出相應的表結構及數據更新。
getWritableDatabase()和getReadableDatabase()方法均可以獲取一個用於操做數據庫的SQLiteDatabase實例。但getWritableDatabase() 方法以讀寫方式打開數據庫,一旦數據庫的磁盤空間滿了,數據庫就只能讀而不能寫,假若使用getWritableDatabase()打開數據庫就會出錯。getReadableDatabase()方法先以讀寫方式打開數據庫,若是數據庫的磁盤空間滿了,就會打開失敗,當打開失敗後會繼續嘗試以只讀方式打開數據庫。sql
注意:getWritableDatabase(),getReadableDatabase的區別是當數據庫寫滿時,調用前者會報錯,調用後者不會,因此若是不是更新數據庫的話,最好調用後者來得到數據庫鏈接。數據庫
代碼:數組
在實際項目開發中,當數據庫表結構發生更新時,應該避免用戶存放於數據庫中的數據丟失。緩存
3、使用SQLiteDatabase操做SQLite數據庫ide
Android提供了一個名爲SQLiteDatabase的類,該類封裝了一些操做數據庫的API,使用該類能夠完成對數據進行添加(Create)、查詢(Retrieve)、更新(Update)和刪除(Delete)操做(這些操做簡稱爲CRUD)。對SQLiteDatabase的學習,咱們應該重點掌握execSQL()和rawQuery()方法。execSQL()方法能夠執行insert、delete、update和CREATE TABLE之類有更改行爲的SQL語句; rawQuery()方法用於執行select語句。
execSQL()方法的使用例子:學習
執行上面SQL語句會往person表中添加進一條記錄,在實際應用中, 語句中的「林計欽」這些參數值會由用戶輸入界面提供,若是把用戶輸入的內容原樣組拼到上面的insert語句, 當用戶輸入的內容含有單引號時,組拼出來的SQL語句就會存在語法錯誤。要解決這個問題須要對單引號進行轉義,也就是把單引號轉換成兩個單引號。有些時候用戶每每還會輸入像「 & 」這些特殊SQL符號,爲保證組拼好的SQL語句語法正確,必須對SQL語句中的這些特殊SQL符號都進行轉義,顯然,對每條SQL語句都作這樣的處理工做是比較煩瑣的。 SQLiteDatabase類提供了一個重載後的execSQL(String sql, Object[] bindArgs)方法,使用這個方法能夠解決前面提到的問題,由於這個方法支持使用佔位符參數(?)。使用例子以下:this
execSQL(String sql, Object[] bindArgs)方法的第一個參數爲SQL語句,第二個參數爲SQL語句中佔位符參數的值,參數值在數組中的順序要和佔位符的位置對應。
SQLiteDatabase的rawQuery()用於執行select語句,使用例子以下:
rawQuery()方法的第一個參數爲select語句;第二個參數爲select語句中佔位符參數的值,若是select語句沒有使用佔位符,該參數能夠設置爲null。帶佔位符參數的select語句使用例子以下:
Cursor是結果集遊標,用於對結果集進行隨機訪問,若是你們熟悉jdbc, 其實Cursor與JDBC中的ResultSet做用很類似。使用moveToNext()方法能夠將遊標從當前行移動到下一行,若是已經移過告終果集的最後一行,返回結果爲false,不然爲true。另外Cursor 還有經常使用的moveToPrevious()方法(用於將遊標從當前行移動到上一行,若是已經移過告終果集的第一行,返回值爲false,不然爲true )、moveToFirst()方法(用於將遊標移動到結果集的第一行,若是結果集爲空,返回值爲false,不然爲true )和moveToLast()方法(用於將遊標移動到結果集的最後一行,若是結果集爲空,返回值爲false,不然爲true ) 。
除了前面給你們介紹的execSQL()和rawQuery()方法, SQLiteDatabase還專門提供了對應於添加、刪除、更新、查詢的操做方法: insert()、delete()、update()和query() 。這些方法其實是給那些不太瞭解SQL語法的菜鳥使用的,對於熟悉SQL語法的程序員而言,直接使用execSQL()和rawQuery()方法執行SQL語句就能完成數據的添加、刪除、更新、查詢操做。
Insert()方法用於添加數據,各個字段的數據使用ContentValues進行存放。ContentValues相似於MAP,相對於MAP,它提供了存取數據對應的put(String key, Xxx value)和getAsXxx(String key)方法,key爲字段名稱,value爲字段值,Xxx指的是各類經常使用的數據類型,如:String、Integer等。
無論第三個參數是否包含數據,執行Insert()方法必然會添加一條記錄,若是第三個參數爲空,會添加一條除主鍵以外其餘字段值爲Null的記錄。Insert()方法內部實際上經過構造insert SQL語句完成數據的添加,Insert()方法的第二個參數用於指定空值字段的名稱,相信你們對該參數會感到疑惑,該參數的做用是什麼?是這樣的:若是第三個參數values 爲Null或者元素個數爲0, 因爲Insert()方法要求必須添加一條除了主鍵以外其它字段爲Null值的記錄,爲了知足SQL語法的須要, insert語句必須給定一個字段名,如:insert into person(name) values(NULL),假若不給定字段名 , insert語句就成了這樣: insert into person() values(),顯然這不知足標準SQL的語法。對於字段名,建議使用主鍵以外的字段,若是使用了INTEGER類型的主鍵字段,執行相似insert into person(personid) values(NULL)的insert語句後,該主鍵字段值也不會爲NULL。若是第三個參數values 不爲Null而且元素的個數大於0 ,能夠把第二個參數設置爲null。
delete()方法的使用:
上面代碼用於從person表中刪除personid小於2的記錄。
update()方法的使用:
上面代碼用於把person表中personid等於1的記錄的name字段的值改成「林計欽」。
query()方法其實是把select語句拆分紅了若干個組成部分,而後做爲方法的輸入參數:
上面代碼用於從person表中查找name字段含有「傳智」的記錄,匹配的記錄按personid降序排序,對排序後的結果略過第一條記錄,只獲取2條記錄。
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各參數的含義:
table:表名。至關於select語句from關鍵字後面的部分。若是是多表聯合查詢,能夠用逗號將兩個表名分開。
columns:要查詢出來的列名。至關於select語句select關鍵字後面的部分。
selection:查詢條件子句,至關於select語句where關鍵字後面的部分,在條件子句容許使用佔位符「?」
selectionArgs:對應於selection語句中佔位符的值,值在數組中的位置與佔位符在語句中的位置必須一致,不然就會有異常。
groupBy:至關於select語句group by關鍵字後面的部分
having:至關於select語句having關鍵字後面的部分
orderBy:至關於select語句order by關鍵字後面的部分,如:personid desc, age asc;
limit:指定偏移量和獲取的記錄數,至關於select語句limit關鍵字後面的部分。
4、使用SQLiteOpenHelper獲取用於操做數據庫的SQLiteDatabase實例
第一次調用getWritableDatabase()或getReadableDatabase()方法後,SQLiteOpenHelper會緩存當前的SQLiteDatabase實例,SQLiteDatabase實例正常狀況下會維持數據庫的打開狀態,因此在你再也不須要SQLiteDatabase實例時,請及時調用close()方法釋放資源。一旦SQLiteDatabase實例被緩存,屢次調用getWritableDatabase()或getReadableDatabase()方法獲得的都是同一實例。
5、使用事務操做SQLite數據庫
使用SQLiteDatabase的beginTransaction()方法能夠開啓一個事務,程序執行到endTransaction() 方法時會檢查事務的標誌是否爲成功,若是程序執行到endTransaction()以前調用了setTransactionSuccessful() 方法設置事務的標誌爲成功則提交事務,若是沒有調用setTransactionSuccessful() 方法則回滾事務。
使用例子以下:
上面兩條SQL語句在同一個事務中執行。