IOS FMDB 數(shù)據(jù)庫(kù)詳解及示例

摘要 IOS操作數(shù)據(jù)庫(kù),SQLite3和coredata是兩個(gè)非常好的選擇,但是對(duì)于我們這些掌握了其他數(shù)據(jù)庫(kù)語(yǔ)言的人來(lái)說(shuō),使用這兩中操作都會(huì)覺(jué)得不方便,SQLite3使用起來(lái)太復(fù)雜了,而使用coredata的時(shí)候卻封裝太死了,我們需要自己些自己的數(shù)據(jù)庫(kù)語(yǔ)句,這時(shí)候,F(xiàn)MDB就是一個(gè)非常不錯(cuò)的選擇!
FMDB 詳解

什么是FMDB
FMDB是iOS平臺(tái)的SQLite數(shù)據(jù)庫(kù)框架
FMDB以O(shè)C的方式封裝了SQLite的C語(yǔ)言API

FMDB的優(yōu)點(diǎn)
使用起來(lái)更加面向?qū)ο螅∪チ撕芏嗦闊⑷哂嗟腃語(yǔ)言代碼
對(duì)比蘋果自帶的Core Data框架,更加輕量級(jí)和靈活
提供了多線程安全的數(shù)據(jù)庫(kù)操作方法,有效地防止數(shù)據(jù)混亂

FMDB的github地址
https://github.com/ccgus/fmdb

廢話少說(shuō),下面來(lái)介紹FMDB的使用吧
FMDB有三個(gè)主要的類
FMDatabase
一個(gè)FMDatabase對(duì)象就代表一個(gè)單獨(dú)的SQLite數(shù)據(jù)庫(kù)
用來(lái)執(zhí)行SQL語(yǔ)句

FMResultSet
使用FMDatabase執(zhí)行查詢后的結(jié)果集

FMDatabaseQueue
用于在多線程中執(zhí)行多個(gè)查詢或更新,它是線程安全的

下面來(lái)打開(kāi)數(shù)據(jù)庫(kù) ,一般都需要數(shù)據(jù)庫(kù)的路徑地址:path
通過(guò)指定SQLite數(shù)據(jù)庫(kù)文件路徑來(lái)創(chuàng)建FMDatabase對(duì)象
FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {

NSLog(@"數(shù)據(jù)庫(kù)打開(kāi)失敗!");
}

path文件路徑有三種情況
1,具體文件路徑
如果不存在會(huì)自動(dòng)創(chuàng)建
2,空字符串@“”
會(huì)在臨時(shí)目錄創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù)
當(dāng)FMDatabase連接關(guān)閉時(shí),數(shù)據(jù)庫(kù)文件也被刪除
3,nil
會(huì)創(chuàng)建一個(gè)內(nèi)存中臨時(shí)數(shù)據(jù)庫(kù),當(dāng)FMDatabase連接關(guān)閉時(shí),數(shù)據(jù)庫(kù)會(huì)被銷毀

CURD操作:
在FMDB中,除查詢以外的所有操作,都稱為“更新”
create、drop、insert、update、delete等

使用executeUpdate:方法執(zhí)行更新

(BOOL)executeUpdate:(NSString)sql, …
(BOOL)executeUpdateWithFormat:(NSString
)format, …
(BOOL)executeUpdate:(NSString)sql withArgumentsInArray:(NSArray )arguments
示例
[db executeUpdate:@“UPDATE t_student SET age = ? WHERE name = ?;“, @20, @“Jack”]

查詢方法

(FMResultSet )executeQuery:(NSString)sql, …
(FMResultSet )executeQueryWithFormat:(NSString)format, …
(FMResultSet )executeQuery:(NSString )sql withArgumentsInArray:(NSArray *)arguments
示例
// 查詢數(shù)據(jù)
FMResultSet *rs = [db executeQuery:@“SELECT * FROM t_student”];

// 遍歷結(jié)果集
while ([rs next]) {

NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
double score = [rs doubleForColumn:@"score"];
}

多線程管理FMDB
FMDatabase這個(gè)類是線程不安全的,如果在多個(gè)線程中同時(shí)使用一個(gè)FMDatabase實(shí)例,會(huì)造成數(shù)據(jù)混亂等問(wèn)題

為了保證線程安全,F(xiàn)MDB提供方便快捷的FMDatabaseQueue類

FMDatabaseQueue的創(chuàng)建
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];

簡(jiǎn)單使用
[queue inDatabase:^(FMDatabase *db) {

[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];

FMResultSet *rs = [db executeQuery:@"select * from t_student"];
while ([rs next]) {
// …
}
}];

使用事務(wù)
[queue inTransaction:^(FMDatabase db, BOOL rollback) {

[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];

FMResultSet *rs = [db executeQuery:@"select * from t_student"];
while ([rs next]) {
// …
}
}];

事務(wù)回滾
*rollback = YES;

-開(kāi)啟/關(guān)閉資料庫(kù)

使用資料庫(kù)的第一件事,就是建立一個(gè)資料庫(kù)。要注意的是,在iOS環(huán)境下,只有document directory 是可以進(jìn)行讀寫(xiě)的。在寫(xiě)程式時(shí)用的那個(gè)Resource資料夾底下的東西都是read-only。因此,建立的資料庫(kù)要放在document 資料夾下。方法如下:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentDirectory = [paths objectAtIndex:0];

NSString *dbPath = [documentDirectory stringByAppendingPathComponent:@"MyDatabase.db"];

FMDatabase

*db = [FMDatabase databaseWithPath:dbPath] ;

if (![db open]) {

NSLog(@“Could not open db.”);

return ;

}

通常這段程式碼會(huì)放在UIViewController中viewDidLoad的函式里。指定路徑后,用[FMDatabase databaseWithPath:]回傳一個(gè)FMDatabase物件,如果該路徑本來(lái)沒(méi)有檔案,會(huì)新增檔案,不然會(huì)開(kāi)啟舊檔。最后呼叫[db open]可以開(kāi)啟該資料庫(kù)檔案,[db close]則關(guān)閉該檔案。

-建立table

如果是新建的資料庫(kù)檔,一開(kāi)始是沒(méi)有table的。建立table的方式很簡(jiǎn)單:

[db executeUpdate:@"CREATE TABLE PersonList (Name text, Age integer, Sex integer, Phone text, Address text, Photo blob)"];

這是FMDB里很常用的指令,[ FMDatabase_object executeUpdate:]后面用NSString塞入SQLite語(yǔ)法,就解決了。因?yàn)檫@篇主要是在講FMDB,所以SQLite的語(yǔ)法就不多說(shuō)了,上述程式碼建立了一個(gè)名為PersonList的table,里面有姓名、年齡、性別、電話、地址和照片。(嗯….很范例的一個(gè)table)

-插入資料

插入資料跟前面一樣,用executeUpdate后面加語(yǔ)法就可以了。比較不同的是,因?yàn)椴迦氲馁Y料會(huì)跟Objective-C的變數(shù)有關(guān),所以在string里使用?號(hào)來(lái)代表這些變數(shù)。

[db executeUpdate:@"INSERT INTO PersonList (Name, Age, Sex, Phone, Address, Photo) VALUES (?,?,?,?,?,?)",

@"Jone", [NSNumber numberWithInt:20], [NSNumber numberWithInt:0], @“091234567”, @“Taiwan, ROC”, [NSData dataWithContentsOfFile:? filepath ]];

其中,在SQLite中的text對(duì)應(yīng)到的是NSString,integer對(duì)應(yīng)NSNumber,blob則是NSData。該做的轉(zhuǎn)換FMDB都做好了,只要了解SQLite語(yǔ)法,應(yīng)該沒(méi)有什么問(wèn)題才是。

-更新資料

太簡(jiǎn)單了,不想講,請(qǐng)看范例:

[db executeUpdate:@"UPDATE PersonList SET Age = ? WHERE Name = ?",[NSNumber numberWithInt:30],@“John”];

-取得資料

取得特定的資料,則需使用FMResultSet物件接收傳回的內(nèi)容:

FMResultSet *rs = [db executeQuery:@"SELECT Name, org.apache.jasper.JasperException: For input stringAge, FROM PersonList"];

while ([rs next]) {

NSString *name = [rs stringForColumn:@"Name"];

int age = [rs intForColumn:@"Age"];

}

[rs close];

用[rs next]可以輪詢query回來(lái)的資料,每一次的next可以得到一個(gè)row里對(duì)應(yīng)的數(shù)值,并用[rs stringForColumn:]或[rs intForColumn:]等方法把值轉(zhuǎn)成Object-C的型態(tài)。取用完資料后則用[rs close]把結(jié)果關(guān)閉。

-快速取得資料

在有些時(shí)候,只會(huì)query某一個(gè)row里特定的一個(gè)數(shù)值(比方只是要找John的年齡),F(xiàn)MDB提供了幾個(gè)比較簡(jiǎn)便的方法。這些方法定義在FMDatabaseAdditions.h,如果要使用,記得先import進(jìn)來(lái)。

//找地址

NSString *address = [db stringForQuery:@"SELECT Address FROM PersonList WHERE Name = ?",@"John”];

//找年齡

int age = [db intForQuery:@"SELECT Age FROM PersonList WHERE Name = ?",@"John”];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容