SQLite3是一款非常輕便易用並且開源的嵌入式數據庫,而SQLite3官方所提供的API接口是用C來提供的,如果用swift進行macOS或是iOS開發的話,就會很不方便,因此有一個國外的大神用swift封裝了SQLite提供的API,並且分享在了GitHub上,稱之爲sqlite.swift,並且最新版本也使用了swift3的語法。原版的說明文檔在此:https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#setters,不過對於像我一樣英語不太好的朋友來說,可能閱讀起來是個障礙。所以這篇文章就來介紹一下sqlite.swift的一些常用的功能和用法。
1.安裝
首先是導入,官方介紹了4種導入的方法,最簡單(也是最手動的)其實是最後一種,就是直接下載然後手動導入,這種導入方法我嘗試過,開發時沒有什麼問題,但是在發佈打包的時候無論如何都不能運行打包後的app,不知道究竟是哪裏的設置沒有搞對。所以本人推薦的是使用CocoaPods進行安裝導入工程,這樣做在工程開發完畢後打包出來的app親測可用的。關於CocoaPods的安裝方法這裏不多做贅述,網上的教程非常多,如果有疑問的話歡迎留言討論。
那麼第一步,我們需要建立一個工程(iOS或macOS),然後打開終端,進入到項目工程的根目錄下,創建一個文件叫"Podfile":
然後用一個你喜歡的文本編輯器打開它,習慣用終端的朋友當然也可以用vim或者nano直接打開。打開之後在文件中寫入:
use_frameworks!
target 'sqlite_test' do
pod 'SQLite.swift', '~> 0.11.3'
end
其中的“sqlite_test”換成你實際的工程名稱,然後在終端執行:
pod install --repo-update
等待安裝完畢(如果是初次安裝需要一段時間從網上下載),如果在整個運行過程中沒有出現紅色的文字段,就說明安裝成功了
然後在你的項目中會多了一些文件,其中有一個擴展名是xcworkspace的,我們以後打開工程就用它。
2.創建數據庫
import SQLite
然後連接數據庫:try? dbCon = Connection("/test/db1.sqlite3", readonly: false)
其中第一個參數是數據庫的路徑,第二個參數是制定數據庫是否爲只讀,如果是false的話可以省略3.執行SQL語句
try? dbCon?.execute("PRAGMA foreign_key = ON;")
函數的參數就寫你要執行的SQL語句就可以了。let result = try? dbCon?.prepare("SELECT * FROM tb1;")
它會得到查詢語句的返回值,至於這個返回值怎麼時候,請參考後面關於數據查詢部分的內容。4.建立表格
Expression<T>
這是後面經常要用到的一個數據類型,它用來表示表的一個數據項,當然也可以表示某一條記錄的某一個數據項,T爲該屬性的類型,如果指定了一個可選類型,那麼表示該數據項可以爲NULL,否則不可以爲NULL,這裏支持的類型和SQLite中類型的對應關係如下:swift | SQLite |
Int | INTEGER |
Double | REAL |
String | TEXT |
nil | NULL |
比如說我要表示一個名爲“name”的數據項,它是String類型的,我就應該寫成:
Expression<String>("name")
下一個要介紹的類型是Expressible,這是一個結構體,實現還是比較複雜的,但是我們基本上可以理解成Expression<Any>,所以如果要見到這個類型,就知道是要傳入Expression的一個實例就好了。try? dbCon?.run(Table("test").create(ifNotExists: true, block:{(tb) in
tb.column(Expression<String>("name"))
tb.column(Expression<String?>("note"))
}))
Table是一個結構體,傳入字符串作爲表的名稱,create方法有很多重載,這裏的第一個參數如果爲true,就表示如果該表已經存在就無視該動作,如果爲false可以省略,這時如果表已存在就會拋出異常(由於本文主要是說明數據庫的使用,這裏所有的異常都沒有理睬,所以用了try?語法,真實開發時應該給予考慮),第二個參數是一個(TableBuilder) -> ()類型的閉包,在閉包中對錶格的每一個數據項進行設置,column方法也有很多重載,常用的有以下幾個:public func column<V : Value>(_ name: Expression<V>, unique: Bool = false, check: Expression<Bool>? = nil, defaultValue: Expression<V>? = nil)
public func column<V : Value>(_ name: Expression<V>, primaryKey: Bool, check: Expression<Bool>? = nil, defaultValue: Expression<V>? = nil)
可以用來制定UNIQUE,CHECK,DEFAULT,PRIMARY KEY屬性,與直接使用SQLite數據庫相同,不再贅述。在次強調,NOT NULL屬性是默認添加的,如果不想添加該屬性,需要在Expression的類型中設置可選類型4.1複合主鍵
tb.primaryKey(Expression<String>("name"), Expression<String>("property"))
調用primaryKey方法,傳入若干個Expression,就可以把它們設置成複合主鍵。4.2外鍵
tb.foreignKey(Expression<String>("username"), references: Table("user"), Expression<String>("username"), update: .cascade, delete: .cascade)
相當於如下的SQL語句:FOREIGN KEY(username) REFERENCES user(username) ON UPDATE cascade ON DELETE cascade;
最後兩個參數如果去掉的話,有外鍵約束的數據記錄將不允許更改或刪除。tb.foreignKey((Expression<String>("forDevice"), Expression<String>("type")), references: Table("device"),( Expression<String>("name"), Expression<String>("property")), update: .cascade, delete: .cascade)
道理與單個的外鍵相同。5.插入記錄
先介紹一個類型,Setter類型,實現比較複雜,簡化以後就是如下的一個結構Expression<T> <- T
顯示一個Expression,然後一個小於號和一個減號,也就是個向左的箭頭,右邊是一個對應類型的表達式,比如說下面這就是合法的表達式:
Expression<Int>("id") <- 1
Expression<String>("name") <- "admin"
insert方法要求的參數就是一個Setter類型,用法如下:try? dbCon?.run(Table("user").insert(Expression<String>("name") <- "admin"))
insert方法還可傳入多個Setter,往後繼續寫就可以插入多個數據項:try? dbCon?.run(Table("user").insert(Expression<String>("name") <- "admin"), Expression<Int>("id") <- 5)
不過就是要注意如果是非空屬性的話,必須得一次性寫全纔可以,不能分多個insert語句插入6.查詢記錄
查詢記錄要用到的類型是Expression<Bool>類型,它可以通過兩個同屬性的Expression<T>運算獲得,或者是一個Expression和一個常數獲得,比如說
Expression<Int>("value") >= 5
就會返回一個Expression<Bool>類型的數據,所以選擇一個表的某些複合條件的行,用到filter函數,傳入的參數是一個Expression<Bool>類型的數據,例如:
let tb = Table("user").filter(Expression<Int>("id") >= 5)
相當於SQL語句:
SELECT * FROM user WHERE id >= 5;
如果選列的話,要用到select 函數,傳入一個或若干個Expression,比如說:
let result = Table("user").select(Expression<String>("name"))
相當於SQL語句:SELECT name FROM user;
當然,上面兩個語句可以疊加使用,比如:
let result = Table("user").select(Expression<String>("name")).filter(Expression<Int>("id") > 8)
相當於SQL語句:
SELECT name FROM user WHERE id > 8;
拿到的結果是一個AnySequence<Row>?類型的數據,這個類型比較討厭,因爲你不能通過下角標直接找到第幾行第幾行的數據,必須用遍歷語句來查找,而且還是一個可選類型,要注意判斷是否爲空然後解包,遍歷中得到的是一個Row類型的數據,可以通過get方法獲得對應的數據,比如下面的例子:
for row in result! {
let name = row.get(Expression<String>("name"))
let id = row.get(Expression<Int>("id"))
Swift.print("name:" + name + "id:\(id)")
}
7.更改記錄
更改記錄其實就是查詢和添加記錄的組合,用到了update函數,不再過多說明,直接看例子:dbCon?.run(Table("user").filter(Expression<Int>("id") > 5 && Expression<String>("sex") == "male").update(Expression<String>("name") <- "haha"))
相當於SQL語句:UPDATE user SET name = "haha" WHERE id > 5 and sex = "male";
8.刪除記錄
刪除記錄用法與更改記錄相同,用到了selete函數,例如:
dbCon?.run(Table("user").fiilter(Expression("id") < 6).delete())
相當於SQL語句:
DELETE FROM user WHERE id < 6;
9.其他功能
其實這些用法都與SQL語句非常的相似,所以用起來也很得心應手,drop函數用於刪除表,alter函數用於更改表結構,等等的功能,只需要稍微看一下函數聲明,一定就會用了。
關於sqlite.swift的簡單介紹就到這裏,如果你有問題或者好的簡介,非常歡迎在下面留言,我們共同來探討,共同學習和進步。