在Android平臺上,集成了嵌入式關系數據庫SQLite。sqlite3支持NULL、INTEGER、REAL(浮點數)、TEXT(字符串文本)和BLOB(二進制對象)數據類型。雖然它只支持五種類型,但SQLite3實際上接受varchar(n)、char(n)和decimal(p,s)。SQLite最大的特點就是可以保存任何字段的各種數據,而不考慮字段聲明的數據類型。例如,可以在整數字段中存儲字符串,在布爾字段中存儲浮點數,或者在字符字段中存儲日期值。但是有壹個例外:定義為整數主鍵的字段只能存儲64位整數,當整數以外的數據保存到這個字段時,就會出錯。另外,在編寫CREATE TABLE語句時,可以省略字段名後面的數據類型信息,比如下面的語句,可以省略name字段的類型信息:
創建表person (personid整數主鍵自動增量,name varchar(20))
SQLite可以解析大多數標準SQL語句,例如:
復制代碼代碼如下:
查詢語句:select * from表名where條件子句group by grouping語句having...order by排序子句
例如:select * from person
select * from person order by id desc
按姓名計數從人員組中選擇姓名(*)& gt;1
分頁SQL類似於mysql。以下SQL語句獲取5條記錄,並跳過前3條記錄。
從賬戶限額5抵銷3中選擇*或從賬戶限額3,5中選擇*。
Insert語句:insert into表名(字段列表)值(值列表)。如:插入到人(姓名,年齡)值('傳智',3)。
Update語句:update table name set field name = value where條件子句。例如:更新人員集名稱= '傳智',其中標識= 10。
Delete語句:從表名中刪除where條件子句。例如,從ID = 10的人處刪除。
其次,使用SQLiteOpenHelper管理數據庫的版本。
我們在編寫數據庫應用軟件時,需要考慮以下幾個問題:由於我們開發的軟件可能安裝在很多用戶的手機上,如果應用使用SQLite數據庫,我們必須在用戶第壹次使用軟件時創建應用使用的數據庫表結構並添加壹些初始化記錄,並且在軟件升級時還需要更新數據表結構。那麽,如何才能在用戶首次使用或升級軟件時,在用戶手機上自動創建應用所需的數據庫表呢?難道我們不能在每壹部需要安裝這個軟件的手機上手動創建數據庫表嗎?因為這個需求是每個數據庫應用都面臨的,所以在Android系統中,為我們提供了壹個名為SQLiteOpenHelper的抽象類,這個抽象類必須被繼承才能使用。它通過管理數據庫版本來實現上述需求。
為了管理數據庫版本,SQLiteOpenHelper類提供了兩個重要的方法,即onCreate(SQLiteDatabase db)和OnUpgrade (SQLite Database DB,Intold Version,IntnewVersion)。前者用於第壹次使用軟件時生成數據庫表,後者用於軟件升級時更新數據庫表結構。當調用SQLiteOpenHelper的getWritableDatabase()或getReadableDatabase()方法獲取用於操作數據庫的SQLiteDatabase實例時,如果數據庫不存在,Android系統會自動生成壹個數據庫,然後調用onCreate()方法。onCreate()方法只有在第壹次生成數據庫時才會被調用。在onCreate()方法中,可以生成數據庫表結構,還可以添加壹些應用程序使用的初始化數據。當數據庫版本改變時,將調用OnUpgrade()方法。壹般軟件升級時需要更改版本號,數據庫的版本由程序員控制。假設數據庫的當前版本是1,由於業務變化,數據庫表結構被修改。這時候就需要升級軟件了。升級軟件時,希望更新用戶手機中的數據庫表結構。為了達到這個目的,我可以將原來的數據庫版本設置為2(有同學問,當然如果妳願意,可以設置為100),在onUpgrade()方法中更新表結構。當軟件版本頻繁升級時,我們可以根據onUpgrade()方法中的原版本號和目標版本號進行判斷,然後進行相應的表結構和數據更新。
getWritableDatabase()和getReadableDatabase()方法都可以獲取用於操作數據庫的SQLiteDatabase實例。但是,getwritetabledatabase()方法通過讀寫來打開數據庫。壹旦數據庫的磁盤空間滿了,數據庫只能讀不能寫。如果使用getwritetabledatabase()打開數據庫,將會出現錯誤。getReadableDatabase()方法首先以讀寫模式打開數據庫。如果數據庫的磁盤空間已滿,將無法打開。當它無法打開時,它將繼續嘗試以只讀模式打開數據庫。
註意:getWritableDatabase()和getReadableDatabase的區別在於,當數據庫已滿時,調用前者會報錯,而調用後者不會,所以如果不是更新數據庫,不如調用後者來獲取數據庫連接。
代碼:
復制代碼代碼如下:
公共類DatabaseHelper擴展SQLiteOpenHelper {
//該類未實例化,因此不能用作父類構造函數的參數,必須聲明為靜態。
私有靜態最終字符串name = " ljqdb//數據庫名稱
私有靜態最終int版本= 1;//數據庫版本
public DatabaseHelper(Context上下文){
//第三個參數CursorFactory指定執行查詢時獲取遊標實例的工廠類。當它設置為null時,意味著使用默認的工廠類。
super(上下文、名稱、null、版本);
}
@覆蓋
public void onCreate(SQLite database db){
db . exec SQL(" CREATE TABLE IF NOT EXISTS person(
personid整數主鍵自動增量,name varchar(20),age INTEGER)");
}
@覆蓋
public void on upgrade(SQLite database db,int oldVersion,int newVersion) {
db . exec SQL(" ALTER TABLE person ADD phone VARCHAR(12)NULL ");//向表中添加壹列
// DROP TABLE IF EXISTS person刪除表。
}
}
在實際項目開發中,更新數據庫表結構時,要避免用戶丟失存儲在數據庫中的數據。
第三,使用SQLiteDatabase操作SQLite數據庫
Android提供了壹個名為SQLiteDatabase的類,封裝了壹些操作數據庫的API。用這個類可以完成添加(創建)、檢索、更新、刪除數據的操作(這些操作簡稱CRUD)。在SQLiteDatabase的學習中,要重點學習execSQL()和rawQuery()。ExecSQL()方法可以執行具有插入、刪除、更新、創建表等變化行為的SQL語句;rawQuery()方法用於執行select語句。
execSQL()方法的使用示例:
復制代碼代碼如下:
SQLiteDatabase數據庫=....;
db . exec SQL(" insert into person(name,age) values ('Lin ',24)");
db . close();
上述SQL語句的執行將向person表添加壹條記錄。在實際應用中,報表中“林”的參數值將由用戶輸入界面提供。如果用戶輸入按原樣組裝到上面的insert語句中,當用戶輸入包含單引號時,組裝的SQL語句將有語法錯誤。要解決這個問題,需要對單引號進行轉義,即將單引號轉換成兩個單引號。有時用戶經常會輸入類似“&”這樣的特殊SQL符號,為了保證組裝後的SQL語句語法正確,必須在SQL語句中對這些特殊SQL符號進行轉義。顯然,對每個SQL語句都這樣做很麻煩。SQLiteDatabase類提供了壹個重載的execsql (String SQL,object [] bind args)方法,由於支持使用占位符參數(?)。使用示例如下:
復制代碼代碼如下:
SQLiteDatabase數據庫=....;
db . exec SQL(" insert into person(name,age) values(?,?)”,新對象[]{“傳智播客”,4 });
db . close();
exec SQL (string SQL,object [] bind args)方法的第壹個參數是SQL語句,第二個參數是SQL語句中占位符參數的值。數組中參數值的順序應該與占位符的位置相對應。
SQLiteDatabase的RawQuery()用於執行select語句,示例如下:
復制代碼代碼如下:
SQLiteDatabase數據庫=....;
cursor cursor = db . raw query(" select * from person ",null);
while (cursor.moveToNext()) {
int personid = cursor . getint(0);//獲取第壹列的值,第壹列的索引從0開始。
string name = cursor . getstring(1);//獲取第二列的值
int age = cursor . getint(2);//獲取第三列的值
}
遊標. close();
db . close();
rawQuery()方法的第壹個參數是select語句;第二個參數是select語句中占位符參數的值,如果select語句不使用占位符,可以將其設置為null。使用帶有占位符參數的select語句的示例如下:
復制代碼代碼如下:
cursor cursor = db . raw query(" select * from person where name like?而年齡=?”,新字符串[]{"%林季芹% "," 4 " });
Cursor是ResultSet遊標,用於隨機訪問結果集。如果妳熟悉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語句,就可以完成數據的添加、刪除、更新和查詢。