FMDB-sqlite第三方類庫

大家好我是你們的顏大人
<p>由于FMDB是建立在SQLite的之上的,所以你至少也該把這篇文章從頭到尾讀一遍。與此同時(shí)借帘,把SQLite的文檔頁 加到你的書簽中洋措。自動引用計(jì)數(shù)(APC)還是手動內(nèi)存管理呢济蝉?</p>
<p>兩種都行,F(xiàn)MDB會在編譯的時(shí)候知道你是用的哪一種菠发,然后進(jìn)行相應(yīng)處理王滤。</p>
<h4>使用方法</h4>

<h5>FMDB有三個主要的類</h5>
1.FMDatabase – 表示一個單獨(dú)的SQLite數(shù)據(jù)庫。 用來執(zhí)行SQLite的命令滓鸠。
2.FMResultSet – 表示FMDatabase執(zhí)行查詢后結(jié)果集
3.FMDatabaseQueue – 如果你想在多線程中執(zhí)行多個查詢或更新雁乡,你應(yīng)該使用該類。這是線程安全的糜俗。

<h5>數(shù)據(jù)庫創(chuàng)建</h5>
創(chuàng)建FMDatabase對象時(shí)參數(shù)為SQLite數(shù)據(jù)庫文件路徑蔗怠。該路徑可以是以下三種之一:
1..文件路徑墩弯。該文件路徑無需真實(shí)存,如果不存在會自動創(chuàng)建寞射。
2..空字符串(@””)渔工。表示會在臨時(shí)目錄創(chuàng)建一個空的數(shù)據(jù)庫,當(dāng)FMDatabase 鏈接關(guān)閉時(shí)桥温,文件也被刪除引矩。
3.NULL. 將創(chuàng)建一個內(nèi)在數(shù)據(jù)庫。同樣的侵浸,當(dāng)FMDatabase連接關(guān)閉時(shí)旺韭,數(shù)據(jù)會被銷毀。

(如需對臨時(shí)數(shù)據(jù)庫或內(nèi)在數(shù)據(jù)庫進(jìn)行一步了解掏觉,請繼續(xù)閱讀:<a target="_blank" rel="external">http://www.sqlite.org/inmemorydb.html</a>)

<figure class="highlight gherkin"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">FMDatabase <span class="keyword"></span>db = [FMDatabase databaseWithPath:<span class="comment">@"/tmp/tmp.db"];</span></span>
</pre></td></tr></table></figure>


<h5>打開數(shù)據(jù)庫</h5>
在和數(shù)據(jù)庫交互 之前区端,數(shù)據(jù)庫必須是打開的。如果資源或權(quán)限不足無法打開或創(chuàng)建數(shù)據(jù)庫澳腹,都會導(dǎo)致打開失敗织盼。

<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
</pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (![<span class="keyword">db</span> <span class="keyword">open</span>]) { </span>
<span class="line"> [<span class="keyword">db</span> release]; </span>
<span class="line"> <span class="keyword">return</span>; </span>
<span class="line"> }</span>
</pre></td></tr></table></figure>


<h5>執(zhí)行更新</h5>
一切不是SELECT命令的命令都視為更新。這包括 CREATE, UPDATE, INSERT,ALTER,COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM, and REPLACE (等)酱塔。
簡單來說沥邻,只要不是以SELECT開頭的命令都是UPDATE命令。

執(zhí)行更新返回一個BOOL值羊娃。YES表示執(zhí)行成功唐全,否則表示有那些錯誤 。你可以調(diào)用 -lastErrorMessage 和 -lastErrorCode方法來得到更多信息蕊玷。

<h5>執(zhí)行查詢</h5>
SELECT命令就是查詢邮利,執(zhí)行查詢的方法是以 -excuteQuery開頭的。

執(zhí)行查詢時(shí)垃帅,如果成功返回FMResultSet對象延届, 錯誤返回nil. 與執(zhí)行更新相當(dāng),支持使用 NSError
參數(shù)挺智。同時(shí)祷愉,你也可以使用 -lastErrorCode和-lastErrorMessage獲知錯誤信息窗宦。

為了遍歷查詢結(jié)果赦颇,你可以使用while循環(huán)。你還需要知道怎么跳到下一個記錄赴涵。使用FMDB媒怯,很簡單實(shí)現(xiàn),就像這樣:

<figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
</pre></td><td class="code"><pre><span class="line"><span class="constant">FMResultSet </span>
s = [db <span class="symbol">executeQuery:</span>@<span class="string">"SELECT * FROM myTable"</span>]; </span>
<span class="line"><span class="keyword">while</span> ([s <span class="keyword">next</span>]) { </span>
<span class="line"> <span class="regexp">//retrieve</span> values <span class="keyword">for</span> each record </span>
<span class="line">}</span>
</pre></td></tr></table></figure>

你必須一直調(diào)用 -[FMResultSet next] 在你訪問查詢返回值之前髓窜,甚至你只想要一個記錄:

<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
</pre></td><td class="code"><pre><span class="line">FMResultSet s = [db <span class="string">executeQuery:</span>@<span class="string">"SELECT COUNT() FROM myTable"</span>]; </span>
<span class="line"> <span class="keyword">if</span> ([s next]) { </span>
<span class="line"> <span class="typename">int</span> totalCount = [s <span class="string">intForColumnIndex:</span><span class="number">0</span>]; </span>
<span class="line"> }</span>
</pre></td></tr></table></figure>


FMResultSet 提供了很多方法來獲得所需的格式的值:

intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:

這些方法也都包括 {type}ForColumnIndex 的這樣子的方法扇苞,參數(shù)是查詢結(jié)果集的列的索引位置欺殿。

你無需調(diào)用 [FMResultSet close]來關(guān)閉結(jié)果集, 當(dāng)新的結(jié)果集產(chǎn)生,或者其數(shù)據(jù)庫關(guān)閉時(shí)鳖敷,會自動關(guān)閉脖苏。

關(guān)閉數(shù)據(jù)庫
當(dāng)使用完數(shù)據(jù)庫,你應(yīng)該 -close 來關(guān)閉數(shù)據(jù)庫連接來釋放SQLite使用的資源定踱。

<figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line"><span class="title">[db close]</span><span class="comment">;</span></span>
</pre></td></tr></table></figure>

<h4>事務(wù)</h4>
FMDatabase是支持事務(wù)的棍潘。
<h5>數(shù)據(jù)凈化(數(shù)據(jù)格式化)</h5>

<p>使用FMDB,插入數(shù)據(jù)前崖媚,你不要花時(shí)間審查你的數(shù)據(jù)亦歉。你可以使用標(biāo)準(zhǔn)的SQLite數(shù)據(jù)綁定語法。</p>
<p>INSERT INTO myTable VALUES (?, ?, ?) </p>
<p>SQLite會識別 “?” 為一個輸入的點(diǎn)位符畅哑, 這樣的執(zhí)行會接受一個可變參數(shù)(或者表示為其他參數(shù)肴楷,如NSArray, NSDictionary,或va_list等),會正確為您轉(zhuǎn)義荠呐。</p>
<p>你也可以選擇使用命名參數(shù)語法赛蔫。</p>
<p>INSERT INTO myTable VALUES (:id, :name, :value) </p>
<p>參數(shù)名必須以冒名開頭。SQLite本身支持其他字符直秆,當(dāng)Dictionary key的內(nèi)部實(shí)現(xiàn)是冒號開頭濒募。注意你的NSDictionary key不要包含冒號。</p>
<figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
</pre></td><td class="code"><pre><span class="line">NSDictionary argsDict = [NSDictionary <span class="string">dictionaryWithObjectsAndKeys:</span>@<span class="string">"My Name"</span>, @<span class="string">"name"</span>, nil]; </span>
<span class="line"> [db <span class="string">executeUpdate:</span>@<span class="string">"INSERT INTO myTable (name) VALUES (:name)"</span> <span class="string">withParameterDictionary:</span>argsDict];</span>
</pre></td></tr></table></figure>
<p>而且圾结,代碼不能這么寫(為什么瑰剃?想想吧。)</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">[db executeUpdate:@"<span class="operator"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> myTable <span class="keyword">VALUES</span> (?)<span class="string">", @"</span>this has <span class="string">" lots of ' bizarre " quotes '"</span>];</span></span>
</pre></td></tr></table></figure>
<p>你應(yīng)該:</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">[db executeUpdate:@"<span class="operator"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> myTable <span class="keyword">VALUES</span> (?)<span class="string">", @"</span>this has <span class="string">" lots of ' bizarre "</span> quotes <span class="string">'"];</span></span></span>
</pre></td></tr></table></figure>
<p>提供給 -executeUpdate: 方法的參數(shù)都必須是對象筝野。就像以下的代碼就無法工作晌姚,且會產(chǎn)生崩潰。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">[db executeUpdate:@"<span class="operator"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> myTable <span class="keyword">VALUES</span> (?)<span class="string">", 42];</span></span></span>
</pre></td></tr></table></figure>
<p> 正確有做法是把數(shù)字打包成 NSNumber對象</p>
<figure class="highlight clojure"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
</pre></td><td class="code"><pre><span class="line"><span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, </span>
<span class="line"><span class="collection">[NSNumber numberWithInt:42]</span>]</span><span class="comment">;</span></span>
</pre></td></tr></table></figure>
<p>或者歇竟,你可以使用 -executeWithFormat: 挥唠,這是NSString風(fēng)格的參數(shù)</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">[db executeUpdateWithFormat:@"<span class="operator"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> myTable <span class="keyword">VALUES</span> (%<span class="keyword">d</span>)<span class="string">", 42];</span></span></span>
</pre></td></tr></table></figure>
<p> -execute
WithFormat: 的方法的內(nèi)部實(shí)現(xiàn)會幫你封裝數(shù)據(jù), 以下這些修飾符都可以使用: %@, %c, %s, %d, %D,%i, %u, %U, %hi, %hu, %qi, %qu, %f, %g, %ld, %lu, %lld, and %llu. 除此之外的修飾符可能導(dǎo)致無法預(yù)知的結(jié)果焕议。 一些情況下宝磨,你需要在SQL語句中使用 % 字符,你應(yīng)該使用 %%盅安。</p>
<p>使用FMDatabaseQueue 及線程安全
在多個線程中同時(shí)使用一個FMDatabase實(shí)例是不明智的』斤保現(xiàn)在你可以為每個線程創(chuàng)建一個FMDatabase對象。 不要讓多個線程分享同一個實(shí)例别瞭,它無法在多個線程中同時(shí)使用窿祥。 若此,壞事會經(jīng)常發(fā)生蝙寨,程序會時(shí)不時(shí)崩潰晒衩,或者報(bào)告異常嗤瞎,或者隕石會從天空中掉下來砸到你Mac Pro. 總之很崩潰。所以听系,不要初始化FMDatabase對象贝奇,然后在多個線程中使用。請使用 FMDatabaseQueue靠胜,它是你的朋友而且會幫助你弃秆。以下是使用方法:</p>
<p>首先創(chuàng)建隊(duì)列。</p>
<figure class="highlight accesslog"><table><tr><td class="gutter"><pre><span class="line">1</span>
</pre></td><td class="code"><pre><span class="line">FMDatabaseQueue *queue = <span class="string">[FMDatabaseQueue databaseQueueWithPath:aPath]</span>;</span>
</pre></td></tr></table></figure>
<p>這樣使用髓帽。</p>
<figure class="highlight clojure"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
</pre></td><td class="code"><pre><span class="line"><span class="collection">[queue inDatabase:^<span class="list">(<span class="keyword">FMDatabase</span> *db)</span> <span class="collection">{ </span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:1]</span>]</span><span class="comment">; </span></span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:2]</span>]</span><span class="comment">; </span></span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:3]</span>]</span><span class="comment">; </span></span>
<span class="line"> FMResultSet *rs = <span class="collection">[db executeQuery:@<span class="string">"select * from foo"</span>]</span><span class="comment">; </span></span>
<span class="line"> while<span class="list">(<span class="collection">[rs next]</span>)</span> <span class="collection">{ </span>
<span class="line"> … </span>
<span class="line"> }</span> </span>
<span class="line">}</span>]</span><span class="comment">;</span></span>
</pre></td></tr></table></figure>
<p>像這樣菠赚,輕松地把簡單任務(wù)包裝到事務(wù)里:</p>
<figure class="highlight clojure"><table><tr><td class="gutter"><pre><span class="line">1</span>
<span class="line">2</span>
<span class="line">3</span>
<span class="line">4</span>
<span class="line">5</span>
<span class="line">6</span>
<span class="line">7</span>
<span class="line">8</span>
<span class="line">9</span>
<span class="line">10</span>
</pre></td><td class="code"><pre><span class="line"><span class="collection">[queue inTransaction:^<span class="list">(<span class="keyword">FMDatabase</span> *db, BOOL *rollback)</span> <span class="collection">{ </span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:1]</span>]</span><span class="comment">; </span></span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:2]</span>]</span><span class="comment">; </span></span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:3]</span>]</span><span class="comment">; </span></span>
<span class="line"> if <span class="list">(<span class="keyword">whoopsSomethingWrongHappened</span>)</span> <span class="collection">{ </span>
<span class="line"> *rollback = YES; return; </span>
<span class="line"> }</span> </span>
<span class="line"> // etc… </span>
<span class="line"> <span class="collection">[db executeUpdate:@<span class="string">"INSERT INTO myTable VALUES (?)"</span>, <span class="collection">[NSNumber numberWithInt:4]</span>]</span><span class="comment">; </span></span>
<span class="line"> }</span>]</span><span class="comment">;</span></span>
</pre></td></tr></table></figure>
<p> FMDatabaseQueue 后臺會建立系列化的G-C-D隊(duì)列,并執(zhí)行你傳給G-C-D隊(duì)列的塊郑藏。這意味著 你從多線程同時(shí)調(diào)用調(diào)用方法衡查,GDC也會按它接收的塊的順序來執(zhí)行。誰也不會吵到誰的腳 必盖,每個人都幸福拌牲。</p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市歌粥,隨后出現(xiàn)的幾起案子塌忽,更是在濱河造成了極大的恐慌,老刑警劉巖失驶,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件土居,死亡現(xiàn)場離奇詭異,居然都是意外死亡嬉探,警方通過查閱死者的電腦和手機(jī)擦耀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涩堤,“玉大人眷蜓,你說我怎么就攤上這事√ノВ” “怎么了吁系?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長白魂。 經(jīng)常有香客問我汽纤,道長,這世上最難降的妖魔是什么碧聪? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任冒版,我火速辦了婚禮液茎,結(jié)果婚禮上逞姿,老公的妹妹穿的比我還像新娘辞嗡。我一直安慰自己,他們只是感情好滞造,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布续室。 她就那樣靜靜地躺著,像睡著了一般谒养。 火紅的嫁衣襯著肌膚如雪挺狰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天买窟,我揣著相機(jī)與錄音丰泊,去河邊找鬼。 笑死始绍,一個胖子當(dāng)著我的面吹牛瞳购,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亏推,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼学赛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吞杭?” 一聲冷哼從身側(cè)響起盏浇,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芽狗,沒想到半個月后绢掰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡童擎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年曼月,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柔昼。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡哑芹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捕透,到底是詐尸還是另有隱情聪姿,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布乙嘀,位于F島的核電站末购,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏虎谢。R本人自食惡果不足惜盟榴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婴噩。 院中可真熱鬧擎场,春花似錦羽德、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至站欺,卻和暖如春姨夹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背矾策。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工磷账, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贾虽。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓够颠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親榄鉴。 傳聞我的和親對象是個殘疾皇子履磨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容