iOS資料庫開發之SQLite和FMDB詳解(附Demo)

NO IMAGE

一.SQLite簡介
先莫急,認真看完簡介,一定對你有幫助的(已經熟知的跳過簡介,當你在公司有同事不會sqlite的時候,你就可以先簡單的說幾句SQLite的簡介以達到裝逼的目的,裝b效果如果100分的話,大多基本上會給你90分了)。
SQLite,是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域專案。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它佔用資源非常的低,在嵌入式裝置中,可能只需要幾百K的記憶體就夠了。它能夠支援Windows/Linux/Unix等等主流的作業系統,同時能夠跟很多程式語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC介面,同樣比起Mysql、PostgreSQL這兩款開源的世界著名資料庫管理系統來講,它的處理速度比他們都快。SQLite第一個Alpha版本誕生於2000年5月。

二.sqlite使用之建立資料庫,建立表,對錶內資料操作等

1.建立資料庫(前面的準備工作(匯入libsqlite3庫)就不介紹了)

- (void)createDataBase{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsStr = [paths objectAtIndex:0];
//應用的文件目錄
NSLog(@"%@",documentsStr);
NSString *database_path = [documentsStr stringByAppendingPathComponent:KDBName];
//開啟資料庫,如果沒有的話,就會在該目錄建立該資料庫。
if(sqlite3_open([database_path UTF8String], &db) != SQLITE_OK) {
sqlite3_close(db);
}
}

2.建立表

 - (void)createTable{
//IF NOT EXISTS 如果不存在 (如果該資料庫已經存在了該表,則sqlite3_exec在執行資料庫操作的時候不會報錯給我們,如果表已經存在了,又沒有加這個判斷的話,會執行不成功並關閉資料庫)
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (ID INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, sex INTEGER, phoneNum VARCHAR);",KTBUserInfo];
[self execSql:sql];
/*
* sqlite資料庫裡面的資料型別參考SQLite資料庫的文件,這裡的sql語句CREATE、INTEGER等關鍵詞,大寫是為了區分這是系統的,並不是規定的,小寫也是能正常通過的,不過,為了規範,建議大寫。
*/
}

3.插入資料

- (void)insertData{
NSString *sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"張三", @"23", @"1",@"18875022022"];
[self execSql:sql];
sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"李四", @"24", @"0",@"18875022023"];
[self execSql:sql];
sql = [NSString stringWithFormat:
@"INSERT INTO '%@' ('name', 'age', 'sex', 'phoneNum') VALUES ('%@', '%@', '%@','%@');",KTBUserInfo, @"王五", @"25", @"1",@"18875022024"];
[self execSql:sql];
}

execSql方法

- (void)execSql:(NSString *)sql{
char *err;
sqlite3_open([[documents stringByAppendingPathComponent:KDBName] UTF8String], &db);
sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err);
sqlite3_close(db);
}

就不貼修改、刪除資料的程式碼了,附件demo裡有詳細程式碼。
只要sql不是SELECT命令的都視為更新操作(使用exec開頭的方法)。就包括《CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE》等等。SELECT命令的話,使用sqlite3_prepare開頭的方法。

4.查詢資料

- (void)queryDataWithTableName:(NSString *)tbName{
sqlite3_open([[documents stringByAppendingPathComponent:KDBName] UTF8String], &db);
NSString *sqlQuery = [NSString stringWithFormat:@"SELECT * FROM %@;",tbName];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(db, [sqlQuery UTF8String], -1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
char *name = (char*)sqlite3_column_text(statement, 1);
NSString *nsNameStr = [[NSString alloc] initWithUTF8String:name];
int age = sqlite3_column_int(statement, 2);
int sex = sqlite3_column_int(statement, 3);
int columnCount = sqlite3_column_count(statement);
if (columnCount == 5) {//為了相容我這裡兩個表,其中一個表少一個欄位,揀個懶
char *phoneNum = (char*)sqlite3_column_text(statement, 4);
NSString *phoneNumStr = [[NSString alloc] initWithUTF8String:phoneNum];                
NSLog(@"%@: name:%@ age:%d sex:%d phoneNum:%@",tbName,nsNameStr,age,sex,phoneNumStr);
}else{
NSLog(@"%@: name:%@ age:%d sex:%d",tbName,nsNameStr,age,sex);
}
}
}else{
NSLog(@"%@查詢資料失敗",tbName);
}
sqlite3_close(db);
}

三.FMDB的用法

由於原生的SQLite在進行資料操作的時候,使用的是C語言中的函式,對於我這種C語言又是小白的人,就會感覺比較麻煩。程式設計師都是懶人,於是,出了一系列的對SQLite的API進行封裝的庫,如FMDB。還有一些其他的,就不列舉了,自行百度。
1.FMDB簡介
https://github.com/ccgus/fmdb‘>FMDB是針對iOS的libsqlite3框架的封裝的一個簡易庫(簡單易學,輕量級,使用靈活),它用起來和SQLite類似,而且,對多執行緒併發操作進行了處理,所以執行緒安全。
2.比較重要的幾個類
FMDB.h 引入了你在使用FMDB過程中可能會用到的幾個類。
FMDatabase 代表一個單獨的SQLite資料庫,用它呼叫方法執行sql語句,類似原生sqlite3。
FMResultSet 在使用FMDatabase執行了查詢的sql語句後,得到的結果集,就是FMResultSet。
FMDatabaseQueue 多執行緒中,執行資料操作,查詢等。

3.使用FMDB建立資料庫和表(首先實現檔案裡宣告全域性變數fmdb)

@interface ViewController (){
sqlite3 *db;
FMDatabase *fmdb;//!< FMDatabase,執行資料操作,查詢。
}
@end
@implementation ViewController
#pragma amrk - fmdb建立資料庫
- (void)fmdbCreate{
NSString *database_path = [documents stringByAppendingPathComponent:KFMDBName];
//資料庫開啟、建立
fmdb = [FMDatabase databaseWithPath:database_path];
}
#pragma amrk - fmdb建立表
- (void)fmdbTableCreate{
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (ID INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, sex INTEGER, phoneNum VARCHAR);",KTBUserInfo];
[self fmdbExecSql:sql];
}
#pragma mark - fmdbUpdate
- (void)fmdbExecSql:(NSString *)sql{
if ([fmdb open]) {
/*
* 只要sql不是SELECT命令的都視為更新操作(使用executeUpdate方法)。就包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等等。SELECT命令的話,使用executeQuery方法。
* 執行更新返回一個BOOL值。YES表示 執行成功,否則表示有錯誤。你可以呼叫 -lastErrorMessage 和 -lastErrorCode方法來得到更多資訊。
*/
if ([fmdb executeUpdate:sql]) {
NSLog(@"%@%@%@",@"fmdb操作表",KTBUserInfo,@"成功!");
}else{
NSLog(@"%@%@%@ lastErrorMessage:%@,lastErrorCode:%d",@"fmdb建立",KTBUserInfo,@"失敗!",fmdb.lastErrorMessage,fmdb.lastErrorCode);
}
}else{
NSLog(@"%@",@"fmdb資料庫開啟失敗!");
}
}    
@end

同樣的道理,只有是運算元據的命令,都是呼叫executeUpdate方法,查詢命令SELECT則呼叫executeQuery開頭的方法。這裡就不列舉增刪改的方法了。

4.fmdb查詢資料

- (void)fmdbSelectData{
NSString *sqlQuery = [NSString stringWithFormat:@"SELECT * FROM %@;",KTBUserInfo];
//根據條件查詢,如果成功返回FMResultSet物件,錯誤返回nil。與執行更新相當,支援使用NSError引數。
FMResultSet *resultSet = [fmdb executeQuery:sqlQuery];
//遍歷結果集合
while ([resultSet  next]){
NSString *name = [resultSet
objectForColumnName:@"name"];
int age = [resultSet intForColumn:@"age"];
int sex = [resultSet intForColumn:@"sex"];
NSString *phone = [resultSet objectForColumnName:@"phoneNum"];
NSLog(@"%@: name:%@ age:%d sex:%d phoneNum:%@",KTBUserInfo,name,age,sex,phone);
}
/*
* fmdb封裝過後的讀取資料是要比原生的sqlite3方便了很多哈
*/
}

5.fmdb多執行緒

- (void)fmdbQueue{
//建立佇列
FMDatabaseQueue *queue = [FMDatabaseQueue
databaseQueueWithPath:[documents stringByAppendingPathComponent:KFMDBName]];
__block BOOL tag = true;
//把任務放到到佇列裡
[queue inTransaction:^(FMDatabase *dbe, BOOL *rollback)
{
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:11]];
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:22]];
tag &= [dbe executeUpdate:@"INSERT INTO userInfo ('age') VALUES (?)",[NSNumber numberWithInt:33]];
//如果有錯誤 回滾
if (!tag){ 
*rollback = YES;
return;
}
}];
}

6.查詢結果獲取資料格式的方法,在FMResultSet.h檔案裡面,搜尋包含ForColumn的方法定義。然後,你就會發現類似這種doubleForColumn、doubleForColumnIndex的方法,註釋也是寫的非常的詳細,不懂英語其實翻譯一下就搞定,機智如我。

四.工具推薦
喜歡用客戶端的自行百度搜尋SQLiteManager for mac 破解版,畢竟找工具還是自力更生。我不喜歡客戶端,有沒有簡單粗暴的直接可以開啟的?有!如果你有裝火狐瀏覽器、就應該會用外掛。不會的也可以下一個火狐瀏覽器,開發用還是很ok的。

點選跳轉原始碼下載地址