iOS-SQLite在項目中實際使用(Swift3)
創建數據庫管理類SQLiteManager
設置類方法創建單例對象
Swift 中單例對象可以直接輸出定義的自身類內的成員變量.
class SQLiteManager: NSObject {
//MARK: - 創建類的靜態實例變量即爲單例對象 let-是線程安全的
static let instance = SQLiteManager()
//對外提供創建單例對象的接口
class func shareInstance() -> SQLiteManager {
return instance
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
操作數據庫
首先需要在項目中導入libsqlite3.tbd框架
SQLite3 框架是一套 C 語言的框架,直接在swift中使用首先需要添加橋接文件
在swift中使用OC/C++/C等文件都需要這個橋接文件.
創建完橋接頭文件還需要將橋接頭文件配置到項目中
然後就可以在swift項目中愉快的使用C語言的各種接口方法了.
打開數據庫
開啓數據庫
class SQLiteManager: NSObject {
//MARK: - 創建類的靜態實例變量即爲單例對象 let-是線程安全的
static let instance = SQLiteManager()
//對外提供創建單例對象的接口
class func shareInstance() -> SQLiteManager {
return instance
}
//MARK: - 數據庫操作
//定義數據庫變量
var db : OpaquePointer? = nil
//打開數據庫
func openDB() -> Bool {
//數據庫文件路徑
let dicumentPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last
let DBPath = (dicumentPath! as NSString).appendingPathComponent("appDB.sqlite")
let cDBPath = DBPath.cString(using: String.Encoding.utf8)
//打開數據庫
//第一個參數:數據庫文件路徑 第二個參數:數據庫對象
// sqlite3_open(<#T##filename: UnsafePointer<Int8>!##UnsafePointer<Int8>!#>, <#T##ppDb: UnsafeMutablePointer<OpaquePointer?>!##UnsafeMutablePointer<OpaquePointer?>!#>)
if sqlite3_open(cDBPath, &db) != SQLITE_OK {
print("數據庫打開失敗")
}
return creatTable();
}
//創建表
func creatTable() -> Bool {
//建表的SQL語句
let creatUserTable = "CREATE TABLE IF NOT EXISTS 't_User' ( 'ID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'name' TEXT,'age' INTEGER,'icon' TEXT);"
let creatCarTable = "CREATE TABLE IF NOT EXISTS 't_Car' ('ID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'type' TEXT,'output' REAL,'master' TEXT);"
//執行SQL語句-創建表 依然,項目中一般不會只有一個表
return creatTableExecSQL(SQL_ARR: [creatUserTable,creatCarTable])
}
//執行建表SQL語句
func creatTableExecSQL(SQL_ARR : [String]) -> Bool {
for item in SQL_ARR {
if execSQL(SQL: item) == false {
return false
}
}
return true
}
//執行SQL語句
func execSQL(SQL : String) -> Bool {
// 1.將sql語句轉成c語言字符串
let cSQL = SQL.cString(using: String.Encoding.utf8)
//錯誤信息
let errmsg : UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>? = nil
if sqlite3_exec(db, cSQL, nil, nil, errmsg) == SQLITE_OK {
return true
}else{
print("SQL 語句執行出錯 -> 錯誤信息: 一般是SQL語句寫錯了 \(errmsg)")
return false
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
一般在app啓動開啓數據庫並建表
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//一般在程序啓動時開始數據庫並建表
if SQLiteManager.shareInstance().openDB() {
print("開啓數據庫成功!")
}
return true
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
數據庫內SQL操作
//執行SQL語句
func execSQL(SQL : String) -> Bool {
// 1.將sql語句轉成c語言字符串
let cSQL = SQL.cString(using: String.Encoding.utf8)
//錯誤信息
let errmsg : UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>? = nil
if sqlite3_exec(db, cSQL, nil, nil, errmsg) == SQLITE_OK {
return true
}else{
print("SQL 語句執行出錯 -> 錯誤信息: 一般是SQL語句寫錯了 \(errmsg)")
return false
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
項目中的Model自定義對象可以自定義一個將自身插入數據庫的方法
//將自身插入數據庫接口
func insertSelfToDB() -> Bool {
//插入SQL語句
let insertSQL = "INSERT INTO 't_User' (name,age,icon) VALUES ('\(name!)',\(age),'\(icon!)');"
if SQLiteManager.shareInstance().execSQL(SQL: insertSQL) {
print("插入數據成功")
return true
}else{
return false
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
模擬插入若干用戶
for i in 1...7 {
let name = "name_\(i)"
let age = arc4random_uniform(18).hashValue + i
let icon = "http://qiuxuewei.com/icon\(i).png"
let user : User = User(name: name, age: age, icon: icon)
if user.insertSelfToDB() {
print("第 \(i) 個用戶插入成功!")
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果需要更新數據庫對應表中數據,直接調用SQL執行方法即可實現
//修改頭像封裝方法
func changeIcon(newIcon : String) {
//包裝修改頭像的SQL語句
let changeIconSQL = "UPDATE 't_User' SET icon='\(newIcon)' WHERE name='name_6'"
if SQLiteManager.shareInstance().execSQL(SQL: changeIconSQL) {
print("name_6 頭像修改成功!")
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
查詢數據庫中對應表中所有數據
在SQLiteManager中封裝一個類方法,可以直接傳入SQL語句輸出數據庫中存儲的數據
其中swift3中對 UnsafePointer 轉 String 做了改動 let s = String(cString: yourCharPointer)
參考:http://stackoverflow.com/questions/39533320/swift-3-convert-a-null-terminated-unsafepointeruint8-to-a-string
//查詢數據庫中數據
func queryDBData(querySQL : String) -> [[String : AnyObject]]? {
//定義遊標對象
var stmt : OpaquePointer? = nil
//將需要查詢的SQL語句轉化爲C語言
if querySQL.lengthOfBytes(using: String.Encoding.utf8) > 0 {
let cQuerySQL = (querySQL.cString(using: String.Encoding.utf8))!
//進行查詢前準備操作
// 1> 參數一:數據庫對象
// 2> 參數二:查詢語句
// 3> 參數三:查詢語句的長度:-1
// 4> 參數四:句柄(遊標對象)
if sqlite3_prepare_v2(db, cQuerySQL, -1, &stmt, nil) == SQLITE_OK {
//準備好之後進行解析
var queryDataArrM = [[String : AnyObject]]()
while sqlite3_step(stmt) == SQLITE_ROW {
//1.獲取 解析到的列(字段個數)
let columnCount = sqlite3_column_count(stmt)
//2.遍歷某行數據
var dict = [String : AnyObject]()
for i in 0..<columnCount {
// 取出i位置列的字段名,作爲字典的鍵key
let cKey = sqlite3_column_name(stmt, i)
let key : String = String(validatingUTF8: cKey!)!
//取出i位置存儲的值,作爲字典的值value
let cValue = sqlite3_column_text(stmt, i)
let value = String(cString:cValue!)
dict[key] = value as AnyObject
}
queryDataArrM.append(dict)
}
return queryDataArrM
}
}
return nil
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
在自定義模型中有必要定義個工廠方法可將數據庫對應表中所有數據取出,以模型數組的形式輸出
//MARK: - 類方法
//將本對象在數據庫內所有數據全部輸出
class func allUserFromDB() -> [User]? {
let querySQL = "SELECT name,age,icon FROM 't_User'"
//取出數據庫中用戶表所有數據
let allUserDictArr = SQLiteManager.shareInstance().queryDBData(querySQL: querySQL)
print(allUserDictArr)
//將字典數組轉化爲模型數組
if let tempUserDictM = allUserDictArr {
// 判斷數組如果有值,則遍歷,並且轉成模型對象,放入另外一個數組中
var userModelArrM = [User]()
for dict in tempUserDictM {
userModelArrM.append(User(dict: dict))
}
return userModelArrM
}
return nil
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
當然,github已經上傳源代碼:https://github.com/qxuewei/Swift-test/tree/master/SQLite%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C-Swift