iOS Sqlite和FMDB的使用、詳解(附Demo)

sqlitedata.png

一.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簡介
<a >FMDB</a>是針對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的。

tmp2e0f5d0a.png

<a >點擊跳轉源碼下載地址</a>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,702評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,615評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,606評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,044評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,826評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,227評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,307評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,447評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,992評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,807評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,001評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,550評論 5 361
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,243評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,667評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,930評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,709評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,996評論 2 374

推薦閱讀更多精彩內容