iOS數據持久化——SQLite(數據庫)

###一、 SQLite基本概述html

  • SQLite,是一款輕型的數據庫,是遵照ACID的關係型數據庫管理系統,它包含在一個相對小的C庫中。git

  • ACID,指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。github

  • SQLite佔用資源很是的低,只須要幾百K的內存就夠了。因此移動端和嵌入式設備的數據存多使用SQLite。sql

  • SQLite可以支持Windows/Linux/Unix等等主流的操做系統,支持多種開發語言,C, C++, PHP, Perl, Java, C#,Python, Ruby等。SQLite雖然很小巧,可是支持的SQL語句不會遜色於其餘開源數據庫,當前使用版本爲SQLite3。數據庫

  • SQLite引擎不是個程序與之通訊的獨立進程,而是鏈接到程序中成爲它的一個主要部分。因此主要的通訊協議是在編程語言內的直接API調用。編程

###二、 導入SQLite系統庫和SQLiteManger下載 iOS中使用SQLite得依賴 libsqlite3.dylib 庫,因此使用前先要導入這個庫。步驟以下:數組

點擊項目文件 -> TARGETS -> Build Phases -> Link Binary With Librarise -> 點擊 + 號,XCode7之後不能直接搜索到libsqlite3.dylib,只能搜到libsqlite3.tbd,須要到指定目錄中添加,因此須要以下圖操做:app

一、點擊Add Other編程語言

輸入圖片說明

二、快捷鍵 command + shift + G 前往文件夾,輸入/user/lib/libsqlite3.dylib 到達庫文件目錄。函數

輸入圖片說明

三、選擇libsqlite3.dylib ,OK了。

輸入圖片說明

爲了提升使用SQLite的效率,一般咱們要結合一個可視化Mac端的SQLite軟件 SQLiteManager 一塊兒完成,以下軟件界面:

輸入圖片說明

###三、 SQLite經常使用結構體\函數解析 SQLite提供是C語言的庫,使用的時候調用的API都是函數,這些經常使用的函數包括數據庫的建立打開、語句的預處理、執行、關閉等。

  • sqlite3: 數據庫結構體,至關於數據庫類。

  • sqlite3_stmt: sql語句結構體,至關於SQL語句類。

  • sqlite3_open(): 建立和打開數據庫,返回值等於 SQLITE_OK 表示成功。

  • sqlite3_exec(): 執行非查詢sql語句,返回值等於 SQLITE_OK 表示執行成功。

  • sqlite3_prepare_v2(): 預處理sql語句,用於數據查詢。

  • sqlite3_step(): 能夠用於屢次執行sql語句,要先使用預處理,用於數據查詢。

  • sqlite3_bind_text(): 綁定sql語句中 ?號對應的參數。

  • sqlite3_column_text(): 從sqlite3_step()的結果中獲取指定列的數據,包含 int,double等多個。

  • sqlite3_finalize():銷燬前面被sqlite3_prepare()建立的預處理語句sqlite3_stmt,在關閉以前完成。

  • sqlite3_close():關閉以前打開的數據庫,使用完後必須關閉數據庫釋放資源。

###四、 建立數據庫

// 一、建立數據庫指針,至關於建立一個數據庫對象。
    sqlite3 *_sqlDB;
	
    // 二、建立數據庫保存的路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dataPath = [docPath stringByAppendingFormat:@"/%@.sqlite",dbName];
    
    // 三、打開數據庫
    int result = sqlite3_open([dataPath UTF8String], &_sqlDB);
    if (result == SQLITE_OK) {
        
		NSLog(@"建立/打開成功!");
    } else {
    
    	NSLog(@"建立/打開失敗!");
    	
        // 四、關閉數據庫
    	sqlite3_close(_sqlDB);
    }

代碼解析

一、數據庫擴展名稱爲.sqlite

二、sqlite3_open()函數包含兩個參數,第一個爲數據庫的路徑由於參數的類型是 char *類型,全部要用[dataPath UTF8String]進行類型轉換,第二個爲數據庫sqlite3指針的地址。

三、若是函數的返回值等於 SQLITE_OK(宏) 表示成功。

四、數據庫打開失敗或者使用完後都要調用sqlite3_close()函數,關閉數據庫釋放資源。

###五、 建立數據庫表

// 一、建立建立表的 SQL 語句
    NSString *sql = @"CREATE TABLE IF NOT EXISTS Person(pID TEXT PRIMARY KEY,pName TEXT,pSex TEXT, pTel TEXT)";
	 
    // 二、執行語句SQL語句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql UTF8String], NULL, NULL, &error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"建立表成功!");
        
    } else {
        
        NSLog(@"建立表失敗!");
        
        sqlite3_close(_sqlDB);
    }

輸入圖片說明

代碼解析:

一、sql語句:**CREATE TABLE IF NOT EXISTS 表名(字段1 數據類型,字段2 數據類型...(還能夠設置字段爲主鍵、外鍵等))"**表示建立一個名稱爲Person的表,表包含pID、pName、pSex、pTel四個字段,主鍵(PRIMARY KEY)爲pID,TEXT爲字段的數據類型表示字符串類型,IF NOT EXISTS表示沒有這個表時再建立有了就不建立了。

二、sqlite3_exec()執行sql語句函數,包含五個參數,第一個是數據庫指針,第二個sql語句(char * 類型),第三個回調函數,若是不須要回調就用NULL。第四個回調函數的的第一個參數沒有用NULL,第五個錯誤信息地址 char **類型。

###六、 添加數據到表

// 一、建立給表添加數據的sql語句
    NSString *pID = @"1002";
    NSString *pName = @"kitty";
    NSString *pSex = @"女";
    NSString *pTel = @"98777331";
    NSString *sql_insert = [NSString stringWithFormat:@"INSERT INTO Person (pID,pName,pSex,pTel) VALUES ('%@','%@','%@','%@')",pID,pName,pSex,pTel];
    
    //二、執行 sql 語句
	 char *error;
    int result = sqlite3_exec(_sqlDB, [sql_insert UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"數據插入成功!");
        
    } else {
        
        NSLog(@"數據插入失敗!");
    }

代碼解析:

一、sql語句:**INSERT INTO Person (字段1,字段2...) VALUES (數據1,數據2...)"**表示在Person表裏的 pID,pName,pSex,pTel 字段中,分別插入對應的值。

二、也sqlite3_exec()執行sql語句,非查詢的sql語句都用這個函數執行。

###七、給數據庫表添加字段(列)

//一、在標準添加字段的 sql 語句
    NSString *culumn = @"pAge INTEGER";
    NSString *sql_addCulumn = [NSString stringWithFormat:@"ALTER TABLE Person ADD COLUMN %@ ",culumn];
    
    //二、執行 sql 語句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql_addCulumn UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"添加字段成功!");
        
    } else {
        
        NSLog(@"添加字段成功!");
    }

代碼解析:

一、sql語句:ALTER TABLE 表名 ADD COLUMN 列名稱和數據類型,表示在Person表格中添加一個字段(一列),這一列名稱叫作 pAge數據類型爲 interger。

二、執行函數也使用sqlite3_exec()

###七、 更新數據

// 一、建立跟新數據的 sql 語句
    NSString *sql_update = [NSString stringWithFormat:@"UPDATE Person SET pAge = %d WHERE pName = 'kitty'",20];
	
    // 二、執行 sql 語句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql_update UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"數據更新成功!");
        
    } else {
        
        NSLog(@"數據更新失敗!");
    }

代碼解析:

一、sql語句:UPDATE 表名 SET 須要修改的數據 WHERE 條件,表示更新Person表格,將pName爲‘kitty’的這些行的 pAge 改成 20。WHERE後面的表示更改的條件。

###八、 刪除數據

// 一、建立 sql 語句
    NSString *sql_Delete = [NSString stringWithFormat:@"DELETE FROM Person WHERE pName = '%@'",@"kitty"];
	
    //二、執行 sql 語句
    char *error;
    int result = sqlite3_exec(_sqlDB, [sql UTF8String], NULL, NULL,&error);
    
    if (result == SQLITE_OK) {
        
        NSLog(@"數據刪除成功!");
        
    } else {
        
        NSLog(@"數據刪除失敗!");
    }

代碼解析

一、sql語句:DELETE FROM 表名 WHERE 條件",表示從Person 表中刪除pName爲‘kitty‘的全部行。

###九、 查詢數據

// 一、建立保存查詢結果的數組
    NSMutableArray *perObjs = [NSMutableArray array];
	 
    // 二、建立查詢的 sql 語句 
    NSString *sql_Select = [NSString stringWithFormat:@"SELECT * FROM Person WHERE pAge > %d",20];
	
    // 三、建立sql語句指針,至關於建立查詢語句對象
    sqlite3_stmt *stmt;
    
    // 四、預處理SQL語句,至關於編譯 sql 過程
    int result = sqlite3_prepare_v2(_sqlDB, [sql UTF8String], -1, &stmt, NULL);
    if(result == SQLITE_OK) {      
		// 五、執行SQL語句
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            
            // 六、獲取對應的字段數據
            char *ID = (char *)sqlite3_column_text(stmt, 0);
            char *name = (char *)sqlite3_column_text(stmt, 1);
            char *sex = (char *)sqlite3_column_text(stmt, 2);
            char *tel = (char *)sqlite3_column_text(stmt, 3);
            int age = sqlite3_column_int(stmt, 4);
            
            // 七、將數據保存到數據mode中
            Person *per = [[Person alloc] init];
            per.pID = [NSString stringWithUTF8String:ID];
            per.pName = [NSString stringWithUTF8String:name];
            per.pSex = [NSString stringWithUTF8String:sex];
            per.pTel = [NSString stringWithUTF8String:tel];
            per.pAge = age;
            
            // 八、將查詢的結果保存在數組中
            [perObjs addObject:per];  
        }
    } else {
        
        sqlite3_close(_sqlDB);
        NSLog(@"查詢數據失敗!");
    }
    // 九、釋放stmt
    sqlite3_finalize(stmt);

代碼解析:

一、sql語句:SELECT * FROM 表名 WHERE 查詢條件,表示從Person表格中查詢pAge大於20的全部行。

二、sqlite3_stmt 至關於sql語句的對象,執行語句、獲取查詢到的取都是對這個對象進行操做。

三、sqlite3_prepare_v2(),sql語句預處理操做,在執行語句前作的事至關於編譯 sql 語句。包含五個參數,第一個數據庫指針,第二個sql語句,第三個能從sql語句中獲取的最大字節數,使用-1表示整個sql語句。第四個sqlite3_stmt對象地址,第五個指向未使用部分的 sql 語句的指針,若是爲前面爲-1就使用NULL。

四、sqlite3_step(),執行 sql 語句,將編譯好的sql語句執行,這個函數可能會屢次執行,由於查詢的數據可能有多條,全部要一個循環語句一塊兒使用。循環條件是sqlite3_step(stmt) == SQLITE_ROW 表示還有其餘行數據。

五、sqlite3_column_text(stmt, 0),獲取查詢到的一行結果中對應列的數據,text表示字符串類型 返回char *類型,0表示獲取第0列的數據。這個函數還有int、double等類型,返回值得類型也對應。選擇列對應的數據類型的函數。

六、使用數據庫查詢到的數據一般要保存到 mode層中,方便使用,全部建立了一個Person對象保存對應的數據。

七、sqlite3_finalize(),使用完查詢對象後要釋放。

###十、Demo下載地址

####連接地址:https://github.com/fuqinglin/SQLDemos.git

####SQLite SQL語句學習:http://www.runoob.com/sqlite/sqlite-tutorial.html

相關文章
相關標籤/搜索