本人ios初學(xué)者聂沙,為自己學(xué)習(xí)方便秆麸,復(fù)制各位大神的學(xué)習(xí)性文章放在自己簡書里,僅作為自己學(xué)習(xí)方便使用及汉,如果作者疑此行為侵權(quán)沮趣,請隨時(shí)聯(lián)系本人刪除,如有共同學(xué)習(xí)者復(fù)制此文章坷随,請注明原出處
寫在前面
SQLite數(shù)據(jù)庫是相比SQLServer房铭、MySQL來說比較輕型的一款數(shù)據(jù)庫,在iOS當(dāng)中温眉,提供了一套比較完整的基于C語言的庫缸匪,可以用來對(duì)SQLite進(jìn)行操作。不過由于SQLite在swift這個(gè)語言當(dāng)中支持很不好类溢,并且會(huì)導(dǎo)致代碼量比較冗余凌蔬,因此一般情況下并不推薦大家使用SQLite來進(jìn)行存儲(chǔ),而是使用iOS對(duì)其的封裝——Core Data。
不過龟梦,確實(shí)出于一些原因大家可能要使用SQLite隐锭,那么我也對(duì)如何在swift當(dāng)中如何使用SQLite數(shù)據(jù)庫進(jìn)行了一番研究窃躲,參考了許多資料计贰,現(xiàn)在整理出來如下:
引入SQLite數(shù)據(jù)庫框架
由于SQLite數(shù)據(jù)庫框架并不屬于swift整合的Cocoa框架,因此需要引入SQLite框架蒂窒。引入的方法很簡單躁倒,在項(xiàng)目本身的 General 下面找到 Linked Frameworks and Libraries 這一項(xiàng),然后鏈接"libsqlite3.dylib"庫即可洒琢。
引入libsqlite3.dylib庫
然后秧秉,由于這個(gè)庫是基于C語言來進(jìn)行使用的,因此我們需要使用一個(gè)OC橋接的頭文件來進(jìn)行操作衰抑。添加OC橋接頭文件的方法有很多象迎,在此我就不就詳細(xì)介紹了:
1.自行創(chuàng)建一個(gè).m文件,然后XCode會(huì)提示您是否添加橋接頭文件呛踊,選擇確認(rèn)后砾淌,橋接頭文件便創(chuàng)建成功了,名為"\(您項(xiàng)目的名稱)-Bridging-Header.h"谭网。
添加橋接頭文件
2.自行添加一個(gè).h文件汪厨,然后在項(xiàng)目設(shè)置的Bulid Setting->Swift Compiler - Code Generation->Objective-C Bridging Header中添加這個(gè)頭文件的路徑。
Build Setting里面的OC橋接頭文件設(shè)置
創(chuàng)建完畢后愉择,在這個(gè)橋接頭文件下面輸入以下語句來引入對(duì)這個(gè)頭文件的引用劫乱。
#import"sqlite3.h"
創(chuàng)建數(shù)據(jù)庫
創(chuàng)建SQLite數(shù)據(jù)庫的方法很簡單,只需要一個(gè)sqlite3_open()方法即可完成锥涕。這個(gè)方法如果數(shù)據(jù)庫存在衷戈,則執(zhí)行“打開”數(shù)據(jù)庫的操作,如果數(shù)據(jù)庫不存在层坠,則執(zhí)行“創(chuàng)建”數(shù)據(jù)庫的操作殖妇。
sqlite3_open()接收兩個(gè)參數(shù),第一個(gè)參數(shù)是數(shù)據(jù)庫文件的路徑窿春,第二個(gè)參數(shù)是一個(gè)輸出參數(shù)拉一,返回一個(gè)到數(shù)據(jù)庫的引用。一般情況下代碼如下:
vardatabase:COpaquePointer=nil
varopenDatabaseResult = sqlite3_open(數(shù)據(jù)庫文件路徑, &database)
第一個(gè)參數(shù)雖然接受的對(duì)象類型是const char *旧乞,但是由于Swift的強(qiáng)大兼容性蔚润,因此其普通的String類型可以轉(zhuǎn)換為這個(gè)類型,也就是說可以直接輸入一個(gè)String類型進(jìn)去尺栖。但是NSString類型卻不能嫡纠,就必須要使用NSString類型的UTF8String這個(gè)方法來獲得NSString對(duì)象對(duì)應(yīng)的char *類型字符串。
由于第二個(gè)參數(shù)要返回一個(gè)到數(shù)據(jù)庫的引用,因此我們就必須要?jiǎng)?chuàng)建一個(gè)模糊結(jié)構(gòu)的指針對(duì)象:COpaquePointer來對(duì)這個(gè)C語言特有的方法來處理除盏。開始這個(gè)指針指向空的地方叉橱,然后執(zhí)行完sqlite3_open()這個(gè)方法后,這個(gè)database便指向了所創(chuàng)建或者打開的數(shù)據(jù)庫者蠕。要注意&引用標(biāo)識(shí)不能遺漏了窃祝。
這個(gè)方法將會(huì)返回一個(gè)Int32類型,標(biāo)定了執(zhí)行的結(jié)果踱侣。如果返回結(jié)果是SQLITE_OK(宏定義值粪小,實(shí)際值為1),那么就表明數(shù)據(jù)庫成功打開抡句,而如果返回結(jié)果是SQLITE_ERROR探膊,就表明數(shù)據(jù)庫打開失敗。具體列表大家可以去sqlite3.h文件中詳看待榔。
關(guān)閉數(shù)據(jù)庫
在對(duì)數(shù)據(jù)庫進(jìn)行操作完畢后(無論是打開數(shù)據(jù)庫逞壁,還是插入、刪除锐锣、查詢數(shù)據(jù)等等)腌闯,都應(yīng)該將數(shù)據(jù)庫關(guān)閉,以釋放線程和內(nèi)存空間刺下。而執(zhí)行關(guān)閉數(shù)據(jù)庫的方法很簡單:
sqlite3_close(database)
對(duì)數(shù)據(jù)庫進(jìn)行操作
對(duì)數(shù)據(jù)庫進(jìn)行操作一般來說指的是對(duì)數(shù)據(jù)庫進(jìn)行插入绑嘹、刪除和更新等等,比如說添加橘茉、刪除表之類的操作工腋。而對(duì)數(shù)據(jù)庫進(jìn)行操作的話,則一般情況下是使用sqlite3_exec()這個(gè)函數(shù)來執(zhí)行SQL語句畅卓。SQL語句才是SQLite數(shù)據(jù)庫的操作重點(diǎn)擅腰,不是么?
var createSQL = "CREATETABLEIFNOTEXISTSTEXTFILED (IDINTEGERPRIMARYKEYAUTOINCREMENT,TEXTTEXT)"
var errorMessage: UnsafeMutablePointer = nil
var createTableResult = sqlite3_exec(database, createSQL, nil, nil, &errorMessage)
對(duì)于Swift語言來說翁潘,SQL語言的輸入很簡單趁冈,只需要把它弄在String類型里面就可以了,但是沒有代碼提示……也沒有錯(cuò)誤提示……因此拜马,需
要很高的SQL語言水準(zhǔn)渗勘。在這里,我的例子中就是簡單的創(chuàng)建一個(gè)名為“TEXTFILED”的表俩莽,它里面含有一個(gè)自增的主鍵ID旺坠,屬于整型,然后還包含一
個(gè)TEXT類型的TEXT屬性扮超。
下一個(gè)則是定義了一個(gè)報(bào)錯(cuò)信息取刃,這個(gè)是為后面函數(shù)做準(zhǔn)備的蹋肮,具體原理和之前介紹的database那貨差不多,都是引用啥的……
重點(diǎn)就是sqlite3_exec這個(gè)函數(shù)璧疗,這個(gè)函數(shù)接收5個(gè)參數(shù)坯辩。第一個(gè)參數(shù)是要執(zhí)行操作的數(shù)據(jù)庫,第二個(gè)參數(shù)是要執(zhí)行的SQL語句崩侠,第三個(gè)參數(shù)是指定操作接收后的回調(diào)函數(shù)漆魔,一般可以不用,第四個(gè)參數(shù)是傳遞給回調(diào)函數(shù)的參數(shù)啦膜,第五個(gè)參數(shù)是用來存儲(chǔ)執(zhí)行出現(xiàn)異常時(shí)的錯(cuò)誤消息有送。
如果要執(zhí)行INSERT淌喻、UPDATE僧家、DELETE等操作,只需要相應(yīng)的更換SQL語句就可以了裸删。至于怎么寫SQL語句八拱,不在本文的討論范圍內(nèi)。
執(zhí)行數(shù)據(jù)庫查詢
使用數(shù)據(jù)庫查詢的話涯塔,一般推薦使用sqlite3_prepare_v2()方法肌稻,這個(gè)方法將查詢結(jié)果存放在一個(gè)區(qū)域當(dāng)中,同樣的這個(gè)區(qū)域我們?nèi)匀贿€是使用指針來指定匕荸。
varsavedData:COpaquePointer=nil
varselectSQL ="SELECT ID, TEXT FROM TEXTFILED"
varselectDataResult = sqlite3_prepare_v2(database, selectSQL, -1, &savedData,nil)
whilesqlite3_step(savedData) ==SQLITE_ROW{
????????? varID= sqlite3_column_int(savedData,0)
????????? vartext =String.fromCString(UnsafePointer(sqlite3_column_text(savedData,1)))? ????????? textfield.text ="ID\(ID):\(text!)"
}sqlite3_finalize(savedData)
首先我們先定義了一個(gè)SQL查詢語句爹谭,就是從TEXTFILED表中查詢ID和TEXT字段。
然后就調(diào)用sqlite3_prepare_v2這個(gè)方法榛搔,第一個(gè)參數(shù)仍然是要執(zhí)行操作的數(shù)據(jù)庫诺凡,第二個(gè)參數(shù)則是要執(zhí)行的SQL語句,第三個(gè)參數(shù)則是SQL語句所可以接受的最大長度践惑,第四個(gè)參數(shù)則是返回的結(jié)果腹泌,實(shí)際上是一個(gè)結(jié)構(gòu)體,第五個(gè)參數(shù)則是指向SQL語句未使用部分的指針尔觉。一般情況下凉袱,我們使用的就是1、2侦铜、4這三個(gè)參數(shù)专甩。
savedData這個(gè)參數(shù)和database是一致的,這個(gè)方法返回的結(jié)果都存儲(chǔ)在了savedData里面钉稍,由于其實(shí)質(zhì)是一個(gè)結(jié)構(gòu)體涤躲,因此我們可以用while循環(huán)來讀取。
使用sqlite3_step()這個(gè)方法可以一行一行地從結(jié)果中取出數(shù)據(jù)嫁盲,然后返回沒一行的所有數(shù)據(jù)篓叶。然后就可以通過sqlite3_column_int烈掠、sqlite3_column_text等方法來取出每一個(gè)字段的值。
要注意的是缸托,在使用·sqlite3_column_text·取出返回值的時(shí)候左敌,由于這個(gè)方法返回的是UnsafePointer,而String的fromString方法則只能接收UnsafePointer類型的方法俐镐,因此需要使用相應(yīng)的構(gòu)造器來對(duì)其進(jìn)行轉(zhuǎn)換矫限。
最后,當(dāng)查詢完成后佩抹,要使用函數(shù)sqlite3_finalize來釋放掉所查詢的數(shù)據(jù)(這個(gè)C語言函數(shù)并不支持ARC)叼风。