拿走即用之FMDB

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;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容