【轉】在iOS開發中使用FMDB

本文轉載自:唐巧的博客

在iOS開發中使用FMDB

APR 22ND, 2012php

前言

SQLite (http://www.sqlite.org/docs.html) 是一個輕量級的關係數據庫。iOS SDK很早就支持了SQLite,在使用時,只須要加入 libsqlite3.dylib 依賴以及引入 sqlite3.h 頭文件便可。可是,原生的SQLite API在使用上至關不友好,在使用時,很是不便。因而,開源社區中就出現了一系列將SQLite API進行封裝的庫,而FMDB (https://github.com/ccgus/fmdb) 則是開源社區中的優秀者。html

FMDB在使用上至關方便。如下是一個簡單的例子:mysql

1
2
3
4
5
6
7
8
9
10
11
NSString* docsdir = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString* dbpath = [docsdir stringByAppendingPathComponent:@"user.sqlite"]; FMDatabase* db = [FMDatabase databaseWithPath:dbpath]; [db open]; FMResultSet *rs = [db executeQuery:@"select * from people"]; while ([rs next]) {  NSLog(@"%@ %@",  [rs stringForColumn:@"firstname"],  [rs stringForColumn:@"lastname"]); } [db close]; 

能夠看到,使用FMDB後的數據庫代碼清晰明瞭,比原生的API優雅多了。另外,FMDB同時兼容ARC和非ARC工程,會自動根據工程配置來調整相關的內存管理代碼。git

使用說明

該使用說明主要翻譯自fmdb的github項目說明文檔: https://github.com/ccgus/fmdbgithub

引入相關文件

首先將FMDB從github上clone下來,而後將如下文件copy到你的工程中:sql

1
2
3
4
5
6
7
8
9
10
FMDatabase.h FMDatabase.m FMDatabaseAdditions.h FMDatabaseAdditions.m FMDatabasePool.h FMDatabasePool.m FMDatabaseQueue.h FMDatabaseQueue.m FMResultSet.h FMResultSet.m 

創建數據庫

創建數據庫只須要以下一行便可,當該文件不存在時,fmdb會本身建立一個。若是你傳入的參數是空串:@「」 ,則fmdb會在臨時文件目錄下建立這個數據庫,若是你傳入的參數是 NULL,則它會創建一個在內存中的數據庫。數據庫

1
FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"]; 

打開數據庫

使用以下語句,若是打開失敗,多是權限不足或者資源不足。一般打開完操做操做後,須要調用close方法來關閉數據庫。安全

1
2
3
4
5
6
7
8
if (![db open]) {  // error   return; } // some operation // ... [db close]; 

執行更新操做

除了Select操做以外,其它的都是更新操做。更新操做使用以下方法,若是有錯誤,能夠用error參數中得到。多線程

1
-[FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:] 

執行查詢操做

查詢操做示例以下。注意:即便操做結果只有一行,也須要先調用FMResultSet的next方法。閉包

1
2
3
4
5
6
7
8
9
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"]; while ([s next]) {  //retrieve values for each record } FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"]; if ([s next]) {  int totalCount = [s intForColumnIndex:0]; } 

FMDB提供以下多個方法來獲取不一樣類型的數據:

1
2
3
4
5
6
7
8
9
10
11
intForColumn: longForColumn: longLongIntForColumn: boolForColumn: doubleForColumn: stringForColumn: dateForColumn: dataForColumn: dataNoCopyForColumn: UTF8StringForColumnIndex: objectForColumn: 

一般狀況下,你並不須要關閉FMResultSet,由於相關的數據庫關閉時,FMResultSet也會被自動關閉。

數據參數

一般狀況下,你能夠按照標準的SQL語句,用?表示執行語句的參數,如:

1
INSERT INTO myTable VALUES (?, ?, ?) 

而後,能夠咱們能夠調用executeUpdate方法來將?所指代的具體參數傳入,一般是用變長參數來傳遞進去的,以下:

1
2
NSString *sql = @"insert into User (name, password) values (?, ?)"; [db executeUpdate:sql, user.name, user.password]; 

這裏須要注意的是,參數必須是NSObject的子類,因此象int,double,bool這種基本類型,須要封裝成對應的包裝類才行,以下所示:

1
2
3
4
// 錯誤,42不能做爲參數 [db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42]; // 正確,將42封裝成 NSNumber 類 [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]]; 

線程安全

若是咱們的app須要多線程操做數據庫,那麼就須要使用FMDatabaseQueue來保證線程安全了。 切記不能在多個線程中共同一個FMDatabase對象而且在多個線程中同時使用,這個類自己不是線程安全的,這樣使用會形成數據混亂等問題。

使用FMDatabaseQueue很簡單,首先用一個數據庫文件地址來初使化FMDatabaseQueue,而後就能夠將一個閉包(block)傳入inDatabase方法中。 在閉包中操做數據庫,而不直接參與FMDatabase的管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 建立,最好放在一個單例的類中 FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; // 使用 [queue inDatabase:^(FMDatabase *db) {  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];  FMResultSet *rs = [db executeQuery:@"select * from foo"];  while ([rs next]) {  // …  } }]; // 若是要支持事務 [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];  if (whoopsSomethingWrongHappened) {  *rollback = YES;  return;  }  // etc…  [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }]; 

工具

爲了查看Sqlite中的數據,一個好的圖形化界面的數據庫管理程序是必不可少的。mysql有phpMyAdmin,那麼sqlite呢?

我主要使用的是Firefox的一個名爲SQLite Manager的插件,安裝此插件後,能夠直接打開後綴名爲sqlite的數據庫文件。SQLite Manager提供一個圖形化的界面來執行數據查詢或更改操做。以下圖所示:

總結

FMDB將SQLite API進行了很友好的封裝,使用上很是方便,對於那些使用純Sqlite API來進行數據庫操做的app,能夠考慮將其遷移到基於FMDB上,這對於之後數據庫相關功能的開發維護,能夠提升很多效率。

我在學習fmdb的時候作了一個小工程用於練習,我把它放到github上了。感興趣的能夠自行下載:https://github.com/tangqiaoboy/FmdbSample

祝你們玩得開心。

相關文章
相關標籤/搜索