SQLite

以下內(nèi)容整理自互聯(lián)網(wǎng),僅用于個(gè)人學(xué)習(xí)


1. Android保存數(shù)據(jù)

Android提供幾種保存數(shù)據(jù)的方式,保證程序在結(jié)束之后這些保存的數(shù)據(jù)不會(huì)丟失。

  • 文本文件保存:可以保存在應(yīng)用程序自己的目錄下,安裝的每個(gè)app都會(huì)在/data/data/目錄下創(chuàng)建個(gè)文件夾,名字和應(yīng)用程序中AndroidManifest.xml文件中的package一樣。
  • SD卡保存
  • Preferences保存:這也是一種經(jīng)常使用的數(shù)據(jù)存儲(chǔ)方法,因?yàn)樗鼈儗?duì)于用戶而言是透明的,并且從應(yīng)用安裝的時(shí)候就存在了。
  • Assets保存:用來(lái)存儲(chǔ)一些只讀數(shù)據(jù),Assets是指那些在assets目錄下的文件,這些文件在你將你的應(yīng)用編譯打包之前就要存在,并且可以在應(yīng)用程序運(yùn)行的時(shí)候被訪問(wèn)到。

但有時(shí)候我們需要對(duì)保存的數(shù)據(jù)進(jìn)行一些復(fù)雜的操作,或者數(shù)據(jù)量很大,超出了文本文件和Preference的性能能的范圍,所以需要一些更加高效的方法來(lái)管理,從Android1.5開(kāi)始,Android就自帶SQLite數(shù)據(jù)庫(kù)了。

SQLite它是一個(gè)獨(dú)立的,無(wú)需服務(wù)進(jìn)程,支持事務(wù)處理,可以使用SQL語(yǔ)言的數(shù)據(jù)庫(kù)。

2. SQLite特性

  • ACID事務(wù) :指數(shù)據(jù)庫(kù)事務(wù)正確執(zhí)行的四個(gè)基本要素的縮寫(xiě)。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個(gè)支持事務(wù)(Transaction)的數(shù)據(jù)庫(kù),必需要具有這四種特性,否則在事務(wù)過(guò)程(Transaction processing)當(dāng)中無(wú)法保證數(shù)據(jù)的正確性,交易過(guò)程極可能達(dá)不到交易方的要求。
  • 無(wú)需安裝和管理配置
  • 支持多種開(kāi)發(fā)語(yǔ)言,C,PHP,Perl,Java,ASP.NET,Python
  • 儲(chǔ)存在單一磁盤(pán)文件中的一個(gè)完整的數(shù)據(jù)庫(kù)
  • 數(shù)據(jù)庫(kù)文件可以在不同字節(jié)順序的機(jī)器間自由的共享
  • 支持?jǐn)?shù)據(jù)庫(kù)大小至2TB
  • 在普通數(shù)據(jù)庫(kù)操作方面比一些流行的數(shù)據(jù)庫(kù)要快
  • 簡(jiǎn)單, 輕松的API
  • 包含TCL綁定, 同時(shí)通過(guò)Wrapper支持其他語(yǔ)言的綁定
  • 良好注釋的源代碼, 并且有著90%以上的測(cè)試覆蓋率
  • 獨(dú)立: 沒(méi)有額外依賴

3. Android中使用SQLite

3.1 創(chuàng)建數(shù)據(jù)庫(kù)

Android 不自動(dòng)提供數(shù)據(jù)庫(kù)。在 Android 應(yīng)用程序中使用 SQLite,必須自己創(chuàng)建數(shù)據(jù)庫(kù),然后創(chuàng)建表、索引,填充數(shù)據(jù)。Android 提供了 SQLiteOpenHelper 幫助你創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),你只要繼承 SQLiteOpenHelper 類(lèi)根據(jù)開(kāi)發(fā)應(yīng)用程序的需要,封裝創(chuàng)建和更新數(shù)據(jù)庫(kù)使用的邏輯就行了。

SQLiteOpenHelper是一個(gè)抽象類(lèi),在這個(gè)類(lèi)里有兩個(gè)抽象方法,OnCreate和OnUpgrade,前者用于第一次創(chuàng)建數(shù)據(jù)庫(kù),后者用于數(shù)據(jù)庫(kù)升級(jí)。

publicclassDatabaseHelperextendsSQLiteOpenHelper{

/**
*@paramcontext上下文環(huán)境(例如,一個(gè)Activity)
*@paramname數(shù)據(jù)庫(kù)名字
*@paramfactory一個(gè)可選的游標(biāo)工廠(通常是Null)
*@paramversion數(shù)據(jù)庫(kù)模型版本的整數(shù)
*
*會(huì)調(diào)用父類(lèi)SQLiteOpenHelper的構(gòu)造函數(shù)
*/
publicDatabaseHelper(Contextcontext,Stringname,CursorFactoryfactory,intversion){
super(context,name,factory,version);

}

/**
*在數(shù)據(jù)庫(kù)第一次創(chuàng)建的時(shí)候會(huì)調(diào)用這個(gè)方法
*
*根據(jù)需要對(duì)傳入的SQLiteDatabase對(duì)象填充表和初始化數(shù)據(jù)。
*/
@Override
publicvoidonCreate(SQLiteDatabasedb){

}

/**
*當(dāng)數(shù)據(jù)庫(kù)需要修改的時(shí)候(兩個(gè)數(shù)據(jù)庫(kù)版本不同),Android系統(tǒng)會(huì)主動(dòng)的調(diào)用這個(gè)方法。
*一般我們?cè)谶@個(gè)方法里邊刪除數(shù)據(jù)庫(kù)表,并建立新的數(shù)據(jù)庫(kù)表.
*/
@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
//三個(gè)參數(shù),一個(gè)SQLiteDatabase對(duì)象,一個(gè)舊的版本號(hào)和一個(gè)新的版本號(hào)

}

@Override
publicvoidonOpen(SQLiteDatabasedb){
//每次成功打開(kāi)數(shù)據(jù)庫(kù)后首先被執(zhí)行
super.onOpen(db);
}
}

當(dāng)Android應(yīng)用運(yùn)行時(shí),SQLiteOpenHelper會(huì)先檢查是否已經(jīng)存在數(shù)據(jù)庫(kù),如果不存在,就創(chuàng)建數(shù)據(jù)庫(kù),然后打開(kāi)數(shù)據(jù)庫(kù),最后調(diào)用OnCreate方法;如果數(shù)據(jù)庫(kù)已存在,而版本號(hào)比上次創(chuàng)建的數(shù)據(jù)庫(kù)版本號(hào)高,就調(diào)用OnUpgrade,用于升級(jí)。

繼承SQLiteOpenHelper之后就擁有了以下兩個(gè)方法:

  • getReadableDatabase()  創(chuàng)建或者打開(kāi)一個(gè)查詢數(shù)據(jù)庫(kù)
  • getWritableDatabase() 創(chuàng)建或者打開(kāi)一個(gè)可寫(xiě)數(shù)據(jù)庫(kù)
DatabaseHelperdatabase=newDatabaseHelper(context);//傳入一個(gè)上下文參數(shù)
SQLiteDatabasedb=null;
db=database.getWritableDatabase();

上面這段代碼會(huì)返回一個(gè) SQLiteDatabase 類(lèi)的實(shí)例,使用這個(gè)對(duì)象,你就可以查詢或者修改數(shù)據(jù)庫(kù)。

3.2 創(chuàng)建表和索引

創(chuàng)建表和索引,需要調(diào)用 SQLiteDatabase 的 execSQL() 方法來(lái)執(zhí)行 DDL 語(yǔ)句。如:

db.execSQL("CREATETABLEuser(_idINTEGERPRIMARYKEY
AUTOINCREMENT,usernameTEXT,passwordTEXT);");

要?jiǎng)h除表和索引,需要使用 execSQL() 方法調(diào)用 DROP INDEX 和 DROP TABLE 語(yǔ)句。

3.3添加數(shù)據(jù)

Android中SQLite數(shù)據(jù)操作(添加、刪除、更新)方式都有兩種,第一種是使用execSQL() 方法執(zhí)行 INSERT, UPDATE, DELETE 等語(yǔ)句,第二種是使用SQLiteDatabase 對(duì)象的 insert()、update()、delete()等方法。

3.3.1 使用execSQL() 添加數(shù)據(jù)

execSQL() 方法適用于所有不返回結(jié)果的 SQL 語(yǔ)句。

Stringsql="insertintouser(username,password)values('afsds','123456');//插入操作的SQL語(yǔ)句
db.execSQL(sql);//執(zhí)行SQL語(yǔ)句

3.3.2 使用 SQLiteDatabase 對(duì)象的 insert()

ContentValuesvalue=newContentValues();
value .put("username","finch");//添加用戶名
value .put("password","123456");//添加密碼
db.insert("user",null,value );//執(zhí)行插入操作

3.4 更新數(shù)據(jù)

3.4.1 使用execSQL方式的實(shí)現(xiàn)

Stringsql="update[user]setpassword='654321'whereusername="finch";//修改的SQL語(yǔ)句
db.execSQL(sql);//執(zhí)行修改

3.4.2 使用SQLiteDatabase 對(duì)象的 update()方法

ContentValuesvalue=newContentValues();
value.put("password","654321");//添加要更改的字段及內(nèi)容
StringwhereClause="username=?";//修改條件
String[]whereArgs={"finch"};//修改條件的參數(shù)
db.update("user",value,whereClause,whereArgs);//執(zhí)行修改

該方法有四個(gè)參數(shù):表名;列名和值的 ContentValues 對(duì)象;可選的 WHERE 條件;可選的填充 WHERE 語(yǔ)句的字符串,這些字符串會(huì)替換 WHERE 條件中的“?”標(biāo)記,update() 根據(jù)條件,更新指定列的值。

3.5 刪除數(shù)據(jù)

3.5.1 使用execSQL方式的實(shí)現(xiàn)

Stringsql="deletefromuserwhereusername="finch";//刪除操作的SQL語(yǔ)句
db.execSQL(sql);//執(zhí)行刪除操作

3.5.2 使用SQLiteDatabase 對(duì)象的delete()方法

StringwhereClause="username=?";//刪除的條件
String[]whereArgs={"finch"};//刪除的條件參數(shù)
db.delete("user",whereClause,whereArgs);//執(zhí)行刪除

3.6 查詢數(shù)據(jù)

查詢數(shù)據(jù)不同于添加、刪除、更新。主要有以下幾種方式。

3.6.1 通過(guò)query實(shí)現(xiàn)查詢

query() 方法用 SELECT 語(yǔ)句段構(gòu)建查詢。SELECT 語(yǔ)句內(nèi)容作為 query() 方法的參數(shù),比如:要查詢的表名,要獲取的字段名,WHERE 條件,包含可選的位置參數(shù),去替代 WHERE 條件中位置參數(shù)的值,GROUP BY 條件,HAVING 條件。除了表名,其他參數(shù)可以是 null。

Cursorc=db.query("user",null,null,null,null,null,null);//查詢并獲得游標(biāo)
if(c.moveToFirst()){//判斷游標(biāo)是否為空
for(inti=0;i<c.getCount();i++){ 
      c.move(i);//移動(dòng)到指定記錄
      Stringusername=c.getString(c.getColumnIndex("username");
      Stringpassword=c.getString(c.getColumnIndex("password"));
}
}

3.6.2 使用 rawQuery() 直接調(diào)用 SELECT 語(yǔ)句

Cursorc=db.rawQuery("select*fromuserwhereusername=?",newStirng[]{"finch"});

if(c.moveToFirst()){
Stringpassword=c.getString(c.getColumnIndex("password"));
}

返回值是一個(gè) cursor 對(duì)象,這個(gè)對(duì)象的方法可以迭代查詢結(jié)果。 如果查詢是動(dòng)態(tài)的,使用這個(gè)方法就會(huì)非常復(fù)雜。例如,當(dāng)你需要查詢的列在程序編譯的時(shí)候不能確定,這時(shí)候使用 query() 方法會(huì)方便很多。

3.6.3 使用游標(biāo)

不管你如何執(zhí)行查詢,都會(huì)返回一個(gè) Cursor,這是 Android 的 SQLite 數(shù)據(jù)庫(kù)游標(biāo)。

  • 通過(guò)使用 getCount() 方法得到結(jié)果集中有多少記錄;
  • 通過(guò) moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍歷所有記錄;
  • 通過(guò) getColumnNames() 得到字段名;
  • 通過(guò) getColumnIndex() 轉(zhuǎn)換成字段號(hào);
  • 通過(guò) getString(),getInt() 等方法得到給定字段當(dāng)前記錄的值;
  • 通過(guò) requery() 方法重新執(zhí)行查詢得到游標(biāo);
  • 通過(guò) close() 方法釋放游標(biāo)資源;

下面給出一個(gè)遍歷的示例

Cursorresult = db.rawQuery("SELECT_id,username,passwordFROMuser");
result.moveToFirst();
while(!result.isAfterLast()){
intid=result.getInt(0);
Stringname=result.getString(1);
Stringpassword=result.getString(2);
//dosomethingusefulwiththese
result.moveToNext();
 }
result.close();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容