FMDB
框架使用(作者離職,求一份工作)
- 將 fmdb 文件夾拖入項目
- 建立橋接文件
- 將 Swift extensions 拖入項目
- 添加 libsqlite3.tdb
FMDB 架構圖

FMDB.png
代碼演練之創(chuàng)建數(shù)據庫到對數(shù)據的增刪改查
import Foundation
/// 數(shù)據庫名稱
private let dbname = "my.db"
class SQLiteManager {
/// 單例 - 全局訪問點
static let sharedManager = SQLiteManager()
/// 全局數(shù)據庫操作隊列 對于常量而言,有一次設置數(shù)值的機會
let queue: FMDatabaseQueue
// 使用 private 可以保證外界統(tǒng)一通過 sharedManager 訪問
private init() {
print("基本準備工作")
var path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
path = (path as NSString).stringByAppendingPathComponent(dbname)
print(path)
// 1. 打開數(shù)據庫
/**
參數(shù):數(shù)據庫的全路徑
返回:數(shù)據庫操作隊列,全局數(shù)據庫的訪問入口
特點:如果數(shù)據庫存在,打開數(shù)據庫,建立隊列
如果數(shù)據庫不存在,新建數(shù)據庫,建立隊列
*/
queue = FMDatabaseQueue(path: path)
// 2. 創(chuàng)建數(shù)據表
createTables()
}
//MARK: - 增加數(shù)據
/// 使用`預編譯` SQL 插入數(shù)據
private func insertPerson4(name: String,age:NSInteger,height:Double) {
// 1. 準備 SQL
/**
特點:
1> 使用 ? 作為參數(shù)的占位符號
2> 提前編譯 SQL,確認語法正確
3> 在真正執(zhí)行 SQL 的時候,使用參數(shù),替換 `?`
4> 預編譯 SQL 中的字符串,不需要使用單引號 '
更加安全,可以留存用戶輸入的所有內容!推薦使用!
*/
let sql = "INSERT INTO T_Person (name, age, height) VALUES (?, ?, ?);"
// 2. 執(zhí)行 sql
queue.inDatabase { (db) -> Void in
// 執(zhí)行單條語句更安全
do {
try db.executeUpdate(sql, name, age, height)
} catch {
print("數(shù)據插入失敗 \\(error)")
}
}
}
// MARK: - 刪除數(shù)據
private func deletePerson(id: Int) {
let sql = "DELETE FROM T_Person WHERE id = :id;"
queue.inDatabase { (db) -> Void in
if db.executeUpdate(sql, withParameterDictionary: ["id": id]) {
print("刪除成功 刪除的數(shù)據行數(shù)為 \\(db.changes())")
} else {
print("刪除失敗")
}
}
}
// MARK: - 更新數(shù)據
private func updatePerson(dict: [String: AnyObject]) {
// 如果條件不符合,會正常執(zhí)行,不會報錯
var sql = "UPDATE T_Person set name = :name, age = :age, height = :height \\n"
sql += "WHERE id = :id;"
queue.inDatabase { (db) -> Void in
if db.executeUpdate(sql, withParameterDictionary: dict) {
print("更新成功 更新的數(shù)據行數(shù)為 \\(db.changes())")
} else {
print("更新失敗")
}
}
}
//MARK: - 查詢數(shù)據
/// 執(zhí)行 SQL 返回結果集合[字典數(shù)組]
///
/// - parameter sql: 要執(zhí)行的 SQL
///
/// - returns: 返回查詢結果,如果 SQL 語法錯誤,返回 nil
func execRecordSet(sql: String) -> [[String: AnyObject]]? {
// `定義`字典數(shù)組,var 的可選項的默認值是 nil
var recordSet: [[String: AnyObject]]?
queue.inDatabase { (db) -> Void in
guard let rs = try? db.executeQuery(sql) else {
print("SQL 語句錯誤")
return
}
// 實例化字典
recordSet = [[String: AnyObject]]()
while rs.next() {
// 1. 知道查詢結果的列數(shù)
let colCount = rs.columnCount()
// 2. 定義一行的字典
var row = [String: AnyObject]()
for col in 0..<colCount {
// 1> 獲得列名
let name = rs.columnNameForIndex(col)
// 2> 獲得值
let value = rs.objectForColumnIndex(col)
// 3> 設置字典
row[name] = value
}
// 添加到數(shù)組
recordSet!.append(row)
}
}
// 返回查詢結果
return recordSet
}
/// 建立數(shù)據表
private func createTables() {
// 1. 準備 sql
let path = NSBundle.mainBundle().pathForResource("db.sql", ofType: nil)!
let sql = try! String(contentsOfFile: path)
print(sql)
// 2. 執(zhí)行 sql,串行隊列同步執(zhí)行,保證數(shù)據安全
queue.inDatabase { (db) -> Void in
// 執(zhí)行 `單條` SQL - 不適合創(chuàng)建數(shù)據表,因為一次只能執(zhí)行一條
// 如果有多個表,會很麻煩
// do {
// try db.executeUpdate(sql)
// } catch {
// print("創(chuàng)建數(shù)據表失敗 \\(error)")
// }
// 執(zhí)行`多條` SQL - 僅適合用于創(chuàng)建數(shù)據表,可以一次創(chuàng)建多個表
if db.executeStatements(sql) {
print("創(chuàng)表成功")
} else {
print("創(chuàng)表失敗")
}
// 使用 FMDB 時,一定注意不要嵌套使用,否則死鎖!
// self.queue.inDatabase({ (db) -> Void in
//
// })
}
print("come here")
}
}
sql常用語句
創(chuàng)建表
CREATE TABLE IF NOT EXISTS "T_Person" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"age" INTEGER,
"heigth" REAL
)
//下邊是sqllite編譯器里邊的語句
/*簡單約束*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER
);
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE,
age INTEGER
);
/*添加主鍵*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER,
score REAL
);
/*添加主鍵*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER,
name TEXT,
age INTEGER,
score REAL,
PRIMARY KEY(id)
);
查詢
/*分頁*/
SELECT * FROM t_student
ORDER BY id ASC LIMIT 30, 10;
/*排序*/
SELECT * FROM t_student
WHERE score > 50
ORDER BY age DESC;
SELECT * FROM t_student
WHERE score < 50
ORDER BY age ASC , score DESC;
/*計量*/
SELECT COUNT(*)
FROM t_student
WHERE age > 50;
/*別名*/
SELECT name as myName, age as myAge, score as myScore
FROM t_student;
SELECT name myName, age myAge, score myScore
FROM t_student;
SELECT s.name myName, s.age myAge, s.score myScore
FROM t_student s
WHERE s.age > 50;
/*查詢*/
SELECT name, age, score FROM t_student;
SELECT * FROM t_student;
修改
UPDATE t_student
SET name = 'MM'
WHERE age = 10;
UPDATE t_student
SET name = 'WW'
WHERE age is 7;
UPDATE t_student
SET name = 'XXOO'
WHERE age < 20;
UPDATE t_student
SET name = 'NNMM'
WHERE age < 50 and score > 10;
/*更新記錄的name*/
UPDATE t_student SET name = 'zhangsan';
刪除
DELETE FROM t_student;
DELETE FROM t_student WHERE age < 50;
插入
INSERT INTO t_student
(age, score, name)
VALUES
('28', 100, 'zhangsan');
INSERT INTO t_student
(name, age)
VALUES
('lisi', '28');
INSERT INTO t_student
(score)
VALUES
(100);
刪除表
/*刪除表*/
DROP TABLE IF EXISTS t_student;