iOS 數據存儲之SQLite3的使用

来源:http://www.cnblogs.com/jukaiit/archive/2016/08/30/5810518.html
-Advertisement-
Play Games

SQLite3是iOS內嵌的資料庫,SQLite3在存儲和檢索大量數據方面非常有效,它使得不必將每個對象都加到記憶體中。還能夠對數據進行負責的聚合,與使用對象執行這些操作相比,獲得結果的速度更快。 SQLite3使用SQL結構化查詢語言,SQL是與關係資料庫交互的標準語言。 SQLite3的使用: 1 ...


SQLite3是iOS內嵌的資料庫,SQLite3在存儲和檢索大量數據方面非常有效,它使得不必將每個對象都加到記憶體中。還能夠對數據進行負責的聚合,與使用對象執行這些操作相比,獲得結果的速度更快。

SQLite3使用SQL結構化查詢語言,SQL是與關係資料庫交互的標準語言。

SQLite3的使用:

1、導入頭文件

#import <sqlite3.h>

2、創建或者打開資料庫

   //創建和打開資料庫
    sqlite3 *database;
    
    //如果sqlite3_open的結果是 SQLITE_OK,表示資料庫已經打開成功。
    //SQLite3是採用可移植的C,資料庫的文件路徑必須以C字元串(非NSString)的形式進行傳遞。
    if (sqlite3_open("/path/databaseFile", &database) != SQLITE_OK) 
{
     sqlite3_close(database); NSAssert(
0, @"Failed to open database");
  }

3、創建一個表

    //創建一個新表
    NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS "
    "(ROW INTEGER PRIMARY KEY, FIELD_DATA TEXT);";
    char *errorMsg;
    
    //sqlite3_exec 針對 SQLite3 運行任何不返回數據的命令
    if (sqlite3_exec (database, [createSQL UTF8String],
                      NULL, NULL, &errorMsg) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Error creating table: %s", errorMsg);
    }

註:sqlite3_exec 執行之後,如果值是SQLITE_OK,則表明執行成功;否則,錯誤信息存儲在errorMsg中。

sqlite3_exec這個方法可以執行那些沒有返回結果的操作,例如創建、插入、刪除等。

4、對錶進行操作

4.1存儲數據到資料庫

  
    sqlite3 *database;
    if (sqlite3_open([[self dataFilePath] UTF8String], &database)
        != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Failed to open database");
    }

     //例子:存儲UITextField的值到資料庫
    for (int i = 0; i < 4; i++) {
        UITextField *field = self.lineFields[i];
        
        //插入操作
        char *update = "INSERT OR REPLACE INTO FIELDS (ROW, FIELD_DATA) "
        "VALUES (?, ?);";
        char *errorMsg = NULL;
        //創建stmt
        sqlite3_stmt *stmt;
        //無論針對哪種數據,任何綁定函數的第一個參數都指向之前在sqlite3_prepare_v2 調用中 使用的sqlite3_stmt
        if (sqlite3_prepare_v2(database, update, -1, &stmt, nil)
            == SQLITE_OK) {
            
            //SQLITE_OK 表示執行成功
            
            /*sqlite3_bind_int(stmt, 1, i);有三個參數:
            
            第一個是sqlite3_stmt類型的變數,在之前的sqlite3_prepare_v2中使用的。
            
            第二個是所約束變數的標簽index。
            
            第三個參數是要加的值。*/
            
            sqlite3_bind_int(stmt, 1, i);
            sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL);
        }
        
        if (sqlite3_step(stmt) != SQLITE_DONE)
            NSAssert(0, @"Error updating table: %s", errorMsg);
        
        //sqlite3_finalize銷毀前面被sqlite3_prepare創建的準備語句
        sqlite3_finalize(stmt);
    }
    //sqlite3_close關閉前面使用sqlite3_open打開的資料庫連接,任何與這個連接相關的準備語句必須在調用這個關閉函數之前被釋放
    sqlite3_close(database);

4.2 對資料庫進行查詢操作

 

    //創建query 和 sqlite3_stmt
    NSString *query = @"SELECT ROW, FIELD_DATA FROM FIELDS ORDER BY ROW";
    sqlite3_stmt *statement;
    
    //無論針對哪種數據,任何綁定函數的第一個參數都指向之前在sqlite3_prepare_v2 調用中 使用的sqlite3_stmt
    if (sqlite3_prepare_v2(database, [query UTF8String],
                           -1, &statement, nil) == SQLITE_OK)
    {
         //sqlite3_step用於執行有前面sqlite3_prepare創建的準備語句。這個語句執行到結果的第一行可用的位置。繼續前進到結果的第二行的話,只需再次調用sqlite3_setp()。繼續調用sqlite3_setp()知道這個語句完成,那些不返回結果的語句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只執行一次就返回
        while (sqlite3_step(statement) == SQLITE_ROW) {
            int row = sqlite3_column_int(statement, 0);
            char *rowData = (char *)sqlite3_column_text(statement, 1);
            
NSString
*fieldValue = [[NSString alloc] initWithUTF8String:rowData]; UITextField *field = self.lineFields[row]; field.text = fieldValue;
}
//sqlite3_finalize銷毀前面被sqlite3_prepare創建的準備語句 sqlite3_finalize(statement); } //sqlite3_close關閉前面使用sqlite3_open打開的資料庫連接,任何與這個連接相關的準備語句必須在調用這個關閉函數之前被釋放 sqlite3_close(database);

5、使用約束變數

實際操作時經常使用叫做約束變數的東西來構造SQL字元串,從而進行插入、查詢或者刪除等。

例如,要執行帶兩個約束變數的插入操作,第一個變數是int類型,第二個是C字元串:

char *sql = "insert into oneTable values (?, ?);";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK) {
    sqlite3_bind_int(stmt, 1, 235);
    sqlite3_bind_text(stmt, 2, "valueString", -1, NULL);
}
if (sqlite3_step(stmt) != SQLITE_DONE)
    NSLog(@"Something is Wrong!");
sqlite3_finalize(stmt);

這裡,sqlite3_bind_int(stmt, 1, 235);有三個參數:

第一個是sqlite3_stmt類型的變數,在之前的sqlite3_prepare_v2中使用的。

第二個是所約束變數的標簽index。

第三個參數是要加的值。

有一些函數多出兩個變數,例如

sqlite3_bind_text(stmt, 2, "valueString", -1, NULL);

這句,第四個參數代表第三個參數中需要傳遞的長度。對於C字元串來說,-1表示傳遞全部字元串。

第五個參數是一個回調函數,比如執行後做記憶體清除工作。

 

6、SQLite3中常用的函數

sqlite3_open():打開資料庫,在操作資料庫之前,首先要打開資料庫。這個函數打開一個sqlite資料庫文件的連接並且返回一個資料庫連接對象。這個操作同時程式中的第一個調用的sqlite函數,同時也是其他sqlite api的先決條件。許多的sqlite介面函數都需要一個資料庫連接對象的指針作為它們的第一個參數。

sqlite3_prepare():將sql文本轉換成一個準備語句(prepared statement)對象,同時返回這個對象的指針。這個介面需要一個資料庫連接指針以及一個要準備的包含SQL語句的文本。它實際上並不執行(evaluate)這個SQL語句,它僅僅為執行準備這個sql語句。

sqlite3_step():執行有前面sqlite3_prepare創建的準備語句。這個語句執行到結果的第一行可用的位置。繼續前進到結果的第二行的話,只需再次調用sqlite3_setp()。繼續調用sqlite3_setp()知道這個語句完成,那些不返回結果的語句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只執行一次就返回。

sqlite3_column():執行sqlite3_step()執行一個準備語句得到的結果集的當前行中返回一個列。每次sqlite3_step得到一個結果集的列停下後,這個過程就可以被多次調用去查詢這個行的各列的值。對列操作是有多個函數,均以sqlite3_column為首碼。

sqlite3_finalize():銷毀前面被sqlite3_prepare創建的準備語句,每個準備語句都必須使用這個函數去銷毀以防止記憶體泄露。在空指針上調用這個函數沒有什麼影響,同時可以準備語句的生命周期的任一時刻調用這個函數:在語句被執行前,一次或多次調用sqlite_reset之後,或者在sqlite3_step任何調用之後不管語句是否完成執行

sqlite3_close():關閉前面使用sqlite3_open打開的資料庫連接,任何與這個連接相關的準備語句必須在調用這個關閉函數之前被釋放

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • //這裡設置游標位置,讓游標位置後移10 textField.leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 10, 0)]; textField.leftViewMode = UITextFieldViewModeAlways; ...
  • 一:UIViewController模態跳轉 知識點1: a: 在官方文檔中,建議這兩者之間通過delegate實現交互。例如使用UIImagePickerController從系統相冊選取照片或者拍照,imagePickerController和彈出它的VC之間就通過UIImagePickerCo ...
  • 廢話不多說,先看上效果,由於動畫錄製的時候幀率限制,只能將動畫放慢了進行錄製,更容易看到效果 這是點擊開始之後代碼 由於動畫使由多個動畫組成,所以第一個動畫完畢之後自動再次開始一個動畫 先解釋一下動畫執行過程 第一步是通過CABasicAnimation 對照片進行縮放 第二步是通過CAKeyfra ...
  • 很久沒有總結,回頭看了一下過期的賬號,記錄的內容少之又少。最近有一些時間,想好好總結記錄一下。 由於很久沒有記錄,想寫的東西很多又很雜,想了一下,一篇一篇羅列知識點和經驗,還不如寫一個系列,記錄一個應用的開發流程和經歷。 主線就是一個應用的構建和開發過程,期間再針對部分節點進行分析和探討。 這篇的標 ...
  • 一:首先瞭解一下生命周期圖 二:UIViewController 生命周期介紹 1.通過alloc init 分配記憶體,初始化controller. 2.loadView loadView方法預設實現[super loadView] 如果在初始化controller時指定了xib文件名,就會根據傳入 ...
  • 一:首先查看一下關於UIGestureRecognizer的定義 UIGestureRecognizer是一個抽象類,定義了所有手勢的基本行為,使用它的子類才能處理具體的手勢 知識點1:關於UIGestureRecognizer的子類如下(下麵這些才是我們平常會直接運用到的類): 實例如下: 二:關 ...
  • 1.1 重新規劃android的項目結構 重新規劃android的目錄結構分兩步: 1.建立AndroidLib類庫,將與業務無關的邏輯轉移到AndroidLib。 acitivity存放的是跟業務無關的Activity基類 cache包存放的是緩存數據和圖片相關的處理 net包存放的是網路底層封裝 ...
  • 在項目中總是需要緩存一些網路請求數據以減輕伺服器壓力,業內也有許多優秀的開源的解決方案。通常的緩存方案都是由記憶體緩存和磁碟緩存組成的,記憶體緩存速度快容量小,磁碟緩存容量大速度慢可持久化。 1、PINCache概述 PINCache 是 Pinterest 的程式員在 Tumblr 的 TMCache ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...