FMDB 框架小結

2021-09-21 17:32:06 字數 4520 閱讀 2131

fmdb 框架是對 sqlite 資料庫 c 語言介面的 objective-c 封裝,即對sqlite3.h檔案中相關介面的封裝。

sqlite3 的使用十分簡單,主要是下面兩個物件、常用函式的使用:

fmdb 框架基本也就涉及這幾個函式。

typedef struct sqlite3 sqlite3;
每乙個開啟的 sqlite 資料庫都由乙個透明的結構體sqlite3來表示,所以可以將sqlite3指標看作乙個物件。

typedef struct sqlite3_stmt sqlite3_stmt;
sqlite3_stmt表示乙個編譯為二進位制形式的 sql 語句,可以進一步執行了。

fmstatement是對sqlite3_stmt的封裝,其成員變數如下,其中_statement指標就指向了sqlite3_stmt結構體。

@inte***ce fmstatement : nsobject
在框架的具體使用過程中,我們並不需要關心該類的使用。

fmdatabase的使用大致遵循下面幾個步驟:

提供乙個資料庫檔案路徑,建立乙個fmdatabase類例項物件。此時,資料庫可能並不存在,這裡只是初始化了一些屬性。

開啟資料庫連線,這裡可以呼叫openopenwithflags:openwithflags:vfs:方法,來實現資料庫的連線,此時可能會建立資料庫,如果其不存在的話。

修改資料庫,該類中提供了多個方法來對資料庫進行更新,方法名以executeupdate字串開頭 ,除了executeupdatewithformat:方法可以直接使用佔位符進行引數的傳遞外,其他方法都是通過使用?佔位符,並同時傳遞集合引數的方式來構造 sqlite 命令的。但是,最終都是要使用sqlite3_bind_*函式進行引數繫結的。

查詢資料庫,查詢資料庫的方法以executequery字串開頭,並且同修改資料庫的方法類似executequerywithformat:方法也是可以直接使用各種佔位符的,而其他方法都是用?作為佔位符的。

關閉資料庫,該類的例項物件在釋放時,會自動去關閉當前開啟的資料庫,當然如有需要,也可以呼叫close方法自行關閉。

fmresultset是使用fmdatabase進行資料庫查詢操作後對查詢結果的封裝類。這個類十分的簡單,實際就是對sqlite3_step()函式的封裝。

在使用過程中,需要呼叫nextnextwitherror:方法獲取下乙個查詢結果,在nextwitherror:方法中實際就是執行了sqlite3_step()函式來獲取查詢結果集合中的一條記錄。而後,根據列名或列索引來獲取具體某個欄位的值。

實際,在具體的方法實現中,都是通過索引來獲取指定欄位的值,這是因為最終獲取值的 sqlite 介面sqlite3_column_*()函式的引數是列的索引值(從 0 開始計算)。

除了通常使用的stringforcolumn:方法來獲取字串值外,還可以使用objectforcolumn:方法獲取諸如nsnumbernsdataobjective-c物件,並且注意如果值為nil那麼返回的是nsnull例項。

另外,該類中還實現了下面兩個方法:

- (id _nullable)objectatindexedsubscript:(int)columnidx;

- (id _nullable)objectforkeyedsubscript:(nsstring *)columnname;

所以在獲取具體欄位的值時,是支援下標運算的。

該類中還提供了乙個方法來支援 kvc 程式設計,如果你的查詢記錄的各個字段完全是某個類的屬性名稱,或者你就是這樣設計的,那麼使用下面這個函式,將會直接把查詢記錄中的各個欄位的結果賦值給所傳遞的物件的相應屬性中。

- (void)kvcmagic:(id)object;
除了各個取值方法,還有兩個屬性可以了解一下,如下:

@property (readonly) nsmutabledictionary *columnnametoindexmap;

@property (nonatomic, readonly, nullable) nsdictionary *resultdictionary;

在多執行緒中直接使用fmdatabse物件操作同乙個資料庫檔案是不安全的,所以 fmdb 第三方庫提供了dmdatabasequeue來方便在多執行緒中操作同乙個資料庫。

在具體的實現中,該類通過建立乙個序列佇列以及乙個fmdatabase例項來同步不同執行緒中對資料庫的操作。

@inte***ce fmdatabasequeue () 

@end

如,在主線程中執行下面的測試函式。

let queue = fmdatabasequeue.init(path: "")

func test()

print("2---- ",thread.current)

}dispatchqueue.init(label: "testqueue2").async )

print("3---- ",thread.current)

}print("1-- ",thread.current)

}

得到的輸出如下:

1-   

1--

2-

3-

2--

2---

2----

3--

3---

3----

當然,這只是一種結果,雖然輸出的結果是不確定的,但是可以發現,2----總是在3--之前列印出來。即,每乙個資料庫操作任務都封裝在**塊中,並提交到fmdatabasequeue例項中的序列佇列中,而且當前任務會被阻塞,直到資料庫操作任務執行完畢。

如果對於乙個資料庫,只涉及到對其的大量讀取,而不涉及其他修改等操作時,可以使用該類。這個資料庫池的實現十分簡單,主要是通過乙個序列佇列和兩個可變陣列實現的。

@inte***ce fmdatabasepool ()
該類中針對同乙個資料庫檔案可以最多建立maximumnumberofdatabasestocreatefmdatabase例項物件用來運算元據庫。應該注意的是,該類使用_lockqueue佇列來保證執行緒池的操作是安全的,但是資料庫的操作並非是執行緒安全的。所以,不應該使用該類去對資料庫進行非唯讀的操作。

對於兩個陣列,_databaseinpool儲存著空閒的fmdatabase例項物件,當需要運算元據庫時,從該陣列中取出例項,而後將其新增到_databaseoutpool陣列中,因為該陣列儲存所有正在使用的fmdatabase例項物件,使用完畢後再歸還到_databaseinpool陣列中,這個過程是執行緒安全的。

該類還定義了兩個非正式協議方法,用來詢問是否向池中新增物件,以及成功新增物件後需要執行什麼額外任務。

@inte***ce nsobject (fmdatabasepooldelegate)

- (bool)databasepool:(fmdatabasepool*)pool shouldadddatabasetopool:(fmdatabase*)database;

- (void)databasepool:(fmdatabasepool*)pool didadddatabase:(fmdatabase*)database;

@end

當然,如果乙個fmdatabase例項物件已經在池中了,那麼便不會再執行databasepool:didadddatabase:方法了,但是你可以通過databasepool:shouldadddatabasetopool:方法來將其關閉。

fmdb框架學習

ios開發常用的儲存方案有兩種 1 使用基於sqlite的開源框架 2 使用蘋果官方的coredata。這裡不討論兩類儲存方式的區別,主要談一談基於sqlit的fmdb框架。原生的sqlite使用上相當不友好,而且還需要自己去控制多執行緒的訪問,比較麻煩,fmdb因其友好的api,安全的多執行緒操作...

Iphone中使用FMDB框架

1 首先得例項化乙個fmdatabase物件,這跟sqlitepersistentobjects 派生乙個子類進行操作是不同。接著開啟乙個資料庫 如果沒有會建立乙個資料庫 view plain paths ios下document路徑,document為ios中可讀寫的資料夾 nsarray pat...

FMDB框架的簡單使用 swift

fmdb框架是oc的,在swift中使用,需要建立乙個橋接檔案轉換 在橋接檔案中匯入fndb的標頭檔案 static let shareinstance sqlitetool 建立和開啟乙個資料庫 如果有就直接開啟,如果沒有,建立乙個再開啟 lazy var db fmdatabase 例項化db物...