iOS中SQLite知識點總結2

數據庫(SQLite)

01-多表查詢

  • 格式:select 字段1,字段2,... from 表名1,表名2;
  • 別名:select 別名1.字段1 as 字段別名1,別名2.字段2 as 字段別名2,... from 表名1 as 別名1,表名2 as 別名2;
  • 能夠給表或字段單獨起別名,as可省略
  • 錶鏈接查詢:select 字段1,字段2,... from 表名1,表名2 where 表名1.id = 表名2.id;
  • 外鍵:
    • 若是表A的主關鍵字是表B中的字段,則該字段成爲表B的外鍵
    • 保持數據的一致性,完整性,主要目的是控制存儲在外鍵表中的數據
    • 使兩張表造成關聯,外鍵只能引用外表中列的值或使用空值

02-代碼實現DDL語句

  • 建立swift項目
  • 導入系統框架sqlite3.tdb(sqlite3.dylib)
  • 在Build Setting中搜索bridging,找到Objective-C Bridging Header,設置一個.h文件路徑爲橋接文件
  • 打開橋接文件,導入頭文件"sqlite3.h"
  • 代碼實現
    • 打開數據庫
      • 獲取沙盒路徑,而後建立數據庫的存儲路徑
      • SQlite3數據庫文件的擴展名沒有一個標準定義,比較流行的選擇是.sqlite三、.db、.db3
    • 使用打開的數據庫,執行DDL語句,建立一個數據庫表
    • 使用打開的數據庫,執行DDL語句,刪除一個數據庫表
    • 將數據庫操做封裝成一個工具類

03-代碼實現DML語句

1.insert綁定參數

  • 準備語句(prepared statement)對象
    • 準備語句對象表明一個簡單SQL語句對象的實例,這個對象一般被稱爲"準備語句"或者"編譯好的SQL語句"或者就直接稱爲"語句"
  • 操做歷程:
    • 使用sqlite3_prepare_v2或者相關的函數建立這個對象,若是執行成功,則返回SQLITE_OK,不然返回一個錯誤碼
    • 使用sqlite3_bind_*()給宿主參數綁定值
    • 經過調用sqlite3_step()一次或屢次來執行這個sql
      • 對於DML語句,若是執行成功,返回SQLITE_DONE
      • 對於DQL語句,經過屢次執行獲取結果集,繼續執行的條件是返回值SQLITE_ROW
    • 使用sqlite3_reset()重置這個語句,而後回到第2步,這個過程作0次或屢次
    • 使用sqlite3_finalize()銷燬這個對象,防止內存泄漏

2.insert插入數據優化

  • sqlite_exec直接執行和未拆解"準備語句"平均執行時間差很少
    • sqlite_exec函數是對"準備語句"的封裝
    • (預處理語句->綁定參數->執行語句->重置語句->釋放語句)
  • 拆解後的"準備語句"執行,效率明顯高了一些,主要緣由是真準遵循了"準備語句"的操做流程
  • 雖然按步驟使用"準備語句",可是執行效率依然不如意
    • 緣由分析:每當SQL調用執行方法執行了一個語句,都會開啓一個叫事務的東西,執行完畢後再提交事務,也就是說,若是執行了10000次SQL語句,就打開和提交了10000次事務,因此形成耗時嚴重.
    • 解決方案:只要在執行多個SQL語句以前,手動開啓事務,在執行完畢以後,手動提交事務,這樣再調用SQL方法執行語句時,就不會再自動開啓和提交事務.
    • 優化後的結果:插入10000條數據,大概耗時0.07秒
  • 得出結論:
    • 若是插入大量數據,請務必手動開啓/提交事務
    • 根據不一樣狀況,選擇使用sqlite3_exec或者"準備語句",若是操做單條語句,使用前者,若是大批量操做,選擇後者

04-代碼實現事務

  • 概念:
    • 事務(Transaction)是併發控制的單位,是用戶定義的一個操做序列.
    • 這些操做要麼都作,要麼都不作,是一個不可分割的工做單位.
    • 經過事務,能夠將邏輯相關的一組操做綁定在一塊兒,保持數據的完整性.
  • 事務一般是以begin transaction開始,以commit transaction或者rollback transaction結束
    • commit表示提交,即提交事務的全部操做.具體的說就是將事務中全部對數據庫的更新寫回磁盤上的物理數據庫中去,事務正常結束.
    • rollback表示回滾,即在事務運行得過程當中發生了某些故障,事務不能繼續進行,系統將事務中對數據庫的全部已完成的操做所有撤銷,回滾到事務開始的狀態.

05-代碼實現DQL語句

1.使用sqlite3_exec

  • 做用:能夠經過回調來獲取結果,步驟相對來講簡單,結果數據類型沒有特定類型(id)
  • 參數說明
    • 參數1:一個打開的數據庫
    • 參數2:須要執行的SQL語句
    • 參數3:查詢結果回調(執行0次或屢次)
      • 參數1:參數4的值
      • 參數2:列的個數
      • 參數3:結果值的數組
      • 參數4:全部列的名稱數組
      • 返回值:0表明繼續執行直到結束,1表明執行1次
    • 參數4:回調函數的第一個值
    • 參數5:錯誤信息

2.使用"準備語句"

  • 做用:能夠處理不一樣特定類型,步驟相對來講複雜
  • 步驟:
    • 經過預處理函數,獲取"準備語句" sqlite3_prepare
    • 不斷執行"準備語句",直到無結果集 while sqlite3_step(stmt) == SQLITE_ROW
    • 獲取列的類型 sqlite3_column_type
    • 根據每列的類型取出不一樣的值
      • sqlite3_column_int64 SQLITE_INTEGER
      • sqlite3_column_double SQLITE_FLOAT
      • sqlite3_column_text SQLITE_TEXT
        • 須要轉換下字符串
        • let cText = UnsafePointer (sqlite3_column_text(stmt,col))
        • let text = String(CString:cText,encoding:NSUTF8StringEncoding)
      • NSNull() SQLITE_NULL
    • 釋放資源 sqlite3_finalize

06-FMDB基本使用

1.什麼是FMDB

  • FMDB是iOS平臺的SQLite框架
  • FMDB以OC的方式封裝了SQLite的C語言API

2.FMDB有什麼優點

  • 使用起來更加面向對象,省去了不少麻煩,冗餘的C語言代碼
  • 提供了多線程安全的數據庫操做方法,有效地防止數據混亂

3.安裝方式

  • Cocoapods:"use_framework!",使用dynamic frameworks的方式集成
  • 手動集成(swift):
    • 導入FMDB文件
    • 導入系統依賴庫sqlite3.0.tbd
    • 創建橋接文件,並導入須要的頭文件

4.核心類

  • FMDatabase
    • 一個FMDatabase對象就表明一個獨立的SQLite數據庫
    • 用來執行SQL語句
  • FMResultSet
    • 使用FMDatabase執行查詢後的結果集
  • FMDatabaseQueue
    • 用於在多線程中執行多個查詢或更新,它是線程安全的

5.使用步驟

  • 打開數據庫
    • 經過指定SQLite數據庫文件路徑來建立FMDatabase對象
    • 文件路徑有3種狀況:
      • 具體文件路徑(若是不存在會自動建立)
      • 空字符串@""(會在臨時目錄建立一個空的數據庫,當FMDatabase鏈接關閉時,數據庫文件也被刪除)
      • nil(會建立一個內存中臨時數據庫,當FMDatabase鏈接關閉時,數據庫會被銷燬)
    • FMDatabase *db = [FMDatabase databaseWithPath:path];
    • if([db open]) { NSLog(@"打開成功"); }
  • 執行更新
    • 在FMDB中,除查詢之外的全部操做,都稱爲"更新"
    • create/drop/insert/update/delete等
    • 使用executeUpdate方法執行更新
  • 執行查詢
  • 關閉數據庫:database.close();

07-FMDatabaseQueue

  • FMDatabase這個類是線程不安全的,若是在多個線程中同時使用一個FMDatabase實例,會形成數據混亂等問題
  • 爲了保證線程安全,FMDB提供方便快捷的FMDatabaseQueue類
  • FMDatabaseQueue的建立
    • FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
  • 簡單使用
    • [queue inDatabase:^(FMDatabase *db){在裏面經過db執行SQL語句獲取結果,對數據進行處理}];
  • 使用事務
    • [queue inTransaction:^(FMDatabase *db,BOOL *rollback){在裏面經過db執行SQL語句獲取結果,對數據進行處理}];
相關文章
相關標籤/搜索