FMDB基本概念
數(shù)據(jù)庫(kù)是存放數(shù)據(jù)的倉(cāng)庫(kù),存放的是多張的表,類(lèi)似于Excel,數(shù)據(jù)以表格的形式展現(xiàn)。常見(jiàn)的數(shù)據(jù)庫(kù):有sqlite, MySQL, SQLServer, Oracle, Access等
FMDB使用的sqlite。sqlite具有靈活小巧,可移植性高的特點(diǎn)。而Mysql一般使用在大型的商業(yè)項(xiàng)目中。而libsqlite3是對(duì)sqlite數(shù)據(jù)庫(kù)進(jìn)行操作的系統(tǒng)庫(kù),也就是系統(tǒng)級(jí)別的api,而FMDB就是對(duì)libsqlite3中的api進(jìn)行了封裝實(shí)現(xiàn)了一些數(shù)據(jù)庫(kù)常用的增刪改查等功能
FMDB基本框架
FMDB主要功能為:
- 數(shù)據(jù)庫(kù)的創(chuàng)建
- 更新語(yǔ)句
- 查詢(xún)語(yǔ)句
- 數(shù)據(jù)庫(kù)的開(kāi)關(guān)(連接和斷開(kāi))
- 數(shù)據(jù)庫(kù)的線程問(wèn)題
FMDB基本框架及其思維導(dǎo)圖如下:

FMDB的線程處理邏輯
首先,SQLite是文件型數(shù)據(jù)庫(kù),其機(jī)制也和文件基本類(lèi)似,也就是 寫(xiě)?yīng)氄迹x共享。FMDB本質(zhì)上只是保證了使用sqlite時(shí)的線程安全而并沒(méi)有實(shí)現(xiàn)讀共享的功能(至于為什么,怎么實(shí)現(xiàn)?),其代碼處理如下:
[self.queue inDatabase:^(FMDatabase * _Nonnull db) {
// 這里是replae語(yǔ)句的相關(guān)方法
[self addDataFrom:0 count:1000];
}];
其本質(zhì)是:
dispatch_sync(_queue, ^() {
FMDatabase *db = [self database];
block(db);
});
而_queue是在初始化FMDatabaseQueue時(shí)生成的一個(gè)串行隊(duì)列,其主要邏輯是:
_queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
備注:
這里的串行隊(duì)列不能使用主隊(duì)列,因?yàn)槭褂弥麝?duì)列會(huì)形成相互阻塞的問(wèn)題。
sqlite多線程模式的定義是:同一個(gè)數(shù)據(jù)庫(kù)連接不能同時(shí)在多個(gè)線程中使用。其關(guān)鍵點(diǎn)是“同時(shí)”,經(jīng)測(cè)試,同一個(gè)連接可以再多個(gè)線程中使用,比如在線程1open,在線程2insert,再在線程3close,但是不能同時(shí)使用,否則會(huì)崩潰。
多線程的目的就是并發(fā),如果不是同時(shí)使用同一個(gè)連接,并發(fā)就失去了意義。所以本質(zhì)上來(lái)講,sqlite3并不支持并發(fā)讀取,只支持并發(fā)讀或者單個(gè)寫(xiě)。FMDB也建議不要在多個(gè)線程中同時(shí)使用一個(gè)FMDatabase對(duì)象就是這個(gè)原理。
sqlite3除了能在編譯階段設(shè)置線程模式,還可以在open的時(shí)候有條件的設(shè)置線程模式,但是FMDB除了openWithFlag外,并沒(méi)有提供這個(gè)接口,為了避免這個(gè)問(wèn)題,F(xiàn)MDB提供了上述的FMDBQueue來(lái)將任務(wù)放到一個(gè)串行隊(duì)列中串行處理,這也就實(shí)現(xiàn)了強(qiáng)行的串行模式下訪問(wèn)數(shù)據(jù)庫(kù)。
綜上所述:FMDB的線程處理就是強(qiáng)行將所有的多線程邏輯在一個(gè)串行隊(duì)列中同步處理。