iOS數(shù)據(jù)持久化方案

1.iOS中數(shù)據(jù)存儲方式

  • plist(NSArray/NSDictionary)
  • preference(NSUserDefaults)
  • NSCoding(NSKeyedArchiver/NSkeyedUnarchiver)
  • SQlite3
  • Core Data

優(yōu)缺點(diǎn)分析

  • plist(屬性列表)是一種XML格式的文件,如果對象是NSString谷誓、NSDictionary、NSArray韧献、NSData、NSNumber等類型嚷那,就可以使用
    writeToFile:atomically:encoding:error:方法直接將對象寫入屬性列表文件中瑞驱。但是對于自定義類無法使用逆趋,而且只能存儲非常簡單的數(shù)據(jù)闷袒。
  • preference(偏好設(shè)置)一般用來保存用戶的賬號滑蚯、密碼、字體大小等,也同樣只能存儲一些簡單數(shù)據(jù)類型,無法存儲自定義對象
  • 基于以上缺點(diǎn),出現(xiàn)了NSCoding技術(shù),NSCoding可以存儲任何對象倦零。只有遵守了NSCoding協(xié)議的對象躏仇,可以實(shí)現(xiàn)encodeWithCoder歸檔對象糟描,initWithCoder恢復(fù)對象。
  • 以上三種存在致命缺陷,無法存儲大量數(shù)據(jù)域慷,也無法實(shí)現(xiàn)非常便捷的CRUD(增刪改查)。每次操作都要從文件中讀取數(shù)據(jù)到內(nèi)存中宙枷,然后增刪改查,再寫入文件,以舊文件覆蓋新文件恤左。大量IO操作,非常耗費(fèi)性能夜赵。
  • SQLite是純C語言嵌入式關(guān)系型數(shù)據(jù)庫,內(nèi)存開銷小乡革、效率高寇僧,廣泛使用于移動客戶端。
  • Core Data基于SQList沸版,是蘋果推出的基于OC版本的數(shù)據(jù)庫技術(shù)嘁傀,比較龐大,比較重量級视粮,包裝了很多層细办,所以效率不及SQLite3。

2.SQLite基本操作

1.準(zhǔn)備工作

背景:在storyboard上添加兩個textField和label馒铃,用來輸入商品數(shù)據(jù)的名稱和價格蟹腾,點(diǎn)擊添加按鈕后痕惋,將其插入數(shù)據(jù)庫。

  1. 導(dǎo)入框架libsqlite3.0.tbd
  2. 包含主頭文件#import<sqlite3.h>
  3. 使用sqlite前先要打開數(shù)據(jù)庫
   // 創(chuàng)建數(shù)據(jù)庫文件名shop.sqlite
    NSString *fileName = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
                          stringByAppendingPathComponent:@"shop.sqlite"];
    // 打開數(shù)據(jù)庫
    int status = sqlite3_open(fileName.UTF8String, &_dataBase);
    if (status == SQLITE_OK) {
        NSLog(@"打開數(shù)據(jù)庫成功");
        // SQL創(chuàng)表語句娃殖,id字段:主鍵,name:名稱,price:價格
        const char *sql = "CREATE TABLE IF NOT EXISTS t_shop (id integer PRIMARY KEY,name text NOT NULL,price real);";
        char *error = NULL;
        // 執(zhí)行sql語句
        sqlite3_exec(self.dataBase, sql, NULL, NULL, &error);
        if (error) {
            NSLog(@"創(chuàng)表失敗:%s",error);
        }
    }else{
        NSLog(@"打開數(shù)據(jù)庫失敗");
    }

代碼解析:sqlite3_open()將根據(jù)文件路徑打開數(shù)據(jù)庫值戳,如果數(shù)據(jù)庫文件不存在,系統(tǒng)會自動創(chuàng)建文件自動初始化數(shù)據(jù)庫炉爆。如果返回值status等于常量SQLITE_OK堕虹,表示數(shù)據(jù)庫打開成功。第二個參數(shù)_dataBase是該控制器sqlite3類型的屬性芬首,是一個打開的數(shù)據(jù)庫實(shí)例赴捞。數(shù)據(jù)庫文件的路徑必須以C字符串(而非NSString)傳入。一般服務(wù)器開發(fā)中打開數(shù)據(jù)庫郁稍,都需要使用sqlite3_close(_dataBase)關(guān)閉數(shù)據(jù)庫赦政,但在移動開發(fā)中,可以不用耀怜。

2.插入數(shù)據(jù)

    //sql語句
    NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_shop(name,price) VALUES('%@',%f);",self.nameField.text,self.priceField.text.doubleValue];
    //執(zhí)行sql恢着,nameField和priceField是兩個textField輸入控件
    sqlite3_exec(self.dataBase, sql.UTF8String, NULL, NULL, NULL);

代碼分析:sqlite3_exec()可以執(zhí)行任何sql語句,比如創(chuàng)表财破、更新掰派、插入、刪除操作等等左痢。但一般不用它執(zhí)行查詢語句靡羡,因?yàn)樗粫祷夭樵兊降臄?shù)據(jù)

3.查詢數(shù)據(jù)

    const char *sql = "SELECT name,price FROM t_shop";
    //stmt指針是用來去除查詢結(jié)果
    sqlite3_stmt *stmt = NULL;
    //準(zhǔn)備
    int status = sqlite3_prepare_v2(self.dataBase, sql, -1, &stmt, NULL);
    if (status == SQLITE_OK) {//SQL語句正確,準(zhǔn)備成功
        while (sqlite3_step(stmt)==SQLITE_ROW) {//成功取出一條數(shù)據(jù)
            const char *name = (const char *)sqlite3_column_text(stmt, 0);//取第一個字段
            const char *price = (const char *)sqlite3_column_text(stmt, 1);//q取第二個字段
            NSLog(@"%s,%s",name,price);
        }
    }
    sqlite3_finalize(stmt);//銷毀sqlite3_stmt對象

代碼解析:sqlite3_step()返回SQLITE_ROW代表遍歷到一條新紀(jì)錄,sqlite3_column_*()用于獲取每個字段對應(yīng)的值俊性,第2個參數(shù)是字段的索引略步,從0開始。

4.模糊查找

// searchText是需要查詢的關(guān)鍵字
NSString *sql = [NSString stringWithFormat:@"SELECT name,price FROM t_shop WHERE name LIKE '%%%@%%' OR  price LIKE '%%%@%%' ;", searchText, searchText];
sqlite3_stmt *stmt = NULL;
    int status = sqlite3_prepare_v2(self.db, sql.UTF8String, -1, &stmt, NULL);
    if (status == SQLITE_OK) { 
        while (sqlite3_step(stmt) == SQLITE_ROW) { 
            const char *name = (const char *)sqlite3_column_text(stmt, 0);
            const char *price = (const char *)sqlite3_column_text(stmt, 1);
            NSLog(@"%s,%s",name,price);            
         }
    }
sqlite3_finalize(stmt);

代碼分析:模糊查找與一般查找除了sql語句不同磅废,其他都是一樣的纳像。唯一需要注意的是,在數(shù)據(jù)庫中%表示任意東西拯勉,%S%表示字符S右邊和左邊可以是任何東西竟趾,在OC中%表示特殊意義,所以要寫兩個(%%)表示一個(%)宫峦。

5.sqlite函數(shù)總結(jié)

// 1.打開數(shù)據(jù)庫
int sqlite3_open(
    const char *filename,   // 數(shù)據(jù)庫的文件路徑
    sqlite3 **ppDb          // 數(shù)據(jù)庫實(shí)例
);

// 2.執(zhí)行任何SQL語句
int sqlite3_exec(
    sqlite3 *,                                  // 一個打開的數(shù)據(jù)庫實(shí)例
    const char *sql,                           // 需要執(zhí)行的SQL語句
    int (*callback)(void*,int,char**,char**),  // SQL語句執(zhí)行完畢后的回調(diào)
    void *,                                    // 回調(diào)函數(shù)的第1個參數(shù)
    char **errmsg                              // 錯誤信息
);

// 3.檢查SQL語句的合法性(查詢前的準(zhǔn)備)
int sqlite3_prepare_v2(
    sqlite3 *db,            // 數(shù)據(jù)庫實(shí)例
    const char *zSql,       // 需要檢查的SQL語句
    int nByte,              // SQL語句的最大字節(jié)長度
    sqlite3_stmt **ppStmt,  // sqlite3_stmt實(shí)例岔帽,用來獲得數(shù)據(jù)庫數(shù)據(jù)
    const char **pzTail
);

// 4.查詢一行數(shù)據(jù)
int sqlite3_step(sqlite3_stmt*); // 如果查詢到一行數(shù)據(jù),就會返回SQLITE_ROW

// 5.利用stmt獲得某一字段的值(字段的下標(biāo)從0開始)
double sqlite3_column_double(sqlite3_stmt*, int iCol);  // 浮點(diǎn)數(shù)據(jù)
int sqlite3_column_int(sqlite3_stmt*, int iCol); // 整型數(shù)據(jù)
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); // 長整型數(shù)據(jù)
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 二進(jìn)制文本數(shù)據(jù)
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);  // 字符串?dāng)?shù)據(jù)

最后

第一篇博客导绷,有很多問題犀勒,還沒寫全,如果想到了再做補(bǔ)充吧。使用這些sqlite原生的C語言API非常費(fèi)力贾费,以后有空介紹一下iOS中最常使用的數(shù)據(jù)庫框架FMDB


That's All

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钦购,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子褂萧,更是在濱河造成了極大的恐慌押桃,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件导犹,死亡現(xiàn)場離奇詭異唱凯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谎痢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門磕昼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人节猿,你說我怎么就攤上這事票从。” “怎么了滨嘱?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵纫骑,是天一觀的道長。 經(jīng)常有香客問我九孩,道長,這世上最難降的妖魔是什么发框? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任躺彬,我火速辦了婚禮,結(jié)果婚禮上梅惯,老公的妹妹穿的比我還像新娘宪拥。我一直安慰自己,他們只是感情好铣减,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布她君。 她就那樣靜靜地躺著,像睡著了一般葫哗。 火紅的嫁衣襯著肌膚如雪缔刹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天劣针,我揣著相機(jī)與錄音校镐,去河邊找鬼。 笑死捺典,一個胖子當(dāng)著我的面吹牛鸟廓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼引谜,長吁一口氣:“原來是場噩夢啊……” “哼牍陌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起员咽,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤毒涧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后骏融,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體链嘀,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年档玻,在試婚紗的時候發(fā)現(xiàn)自己被綠了怀泊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡误趴,死狀恐怖霹琼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凉当,我是刑警寧澤枣申,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站看杭,受9級特大地震影響忠藤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜楼雹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一模孩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贮缅,春花似錦榨咐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桂肌,卻和暖如春数焊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轴或。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工昌跌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人照雁。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓蚕愤,卻偏偏與公主長得像答恶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子萍诱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 一悬嗓、直接寫入(writeToFile) 1.使用場景 生成plist文件,以字典的形式保存簡單配置信息裕坊,如i...
    337b94dc718f閱讀 824評論 0 0
  • 技術(shù)由來 數(shù)據(jù)持久化是iOS開發(fā)中必不可少的一項(xiàng)技能包竹。因?yàn)殚_發(fā)中我們多會涉及到用戶信息存儲、文件存儲籍凝、應(yīng)用內(nèi)容緩存...
    無神閱讀 1,148評論 0 13
  • 在介紹存儲方案之前有必要說下沙盒機(jī)制周瞎,詳見:iOS中的沙盒目錄 數(shù)據(jù)持久化,其實(shí)就是將數(shù)據(jù)寫入到硬盤的方式饵蒂,使得A...
    大米卡卡閱讀 353評論 0 0
  • 種類: plist存儲:使用XML鍵值對持久化声诸,它適用于少量且數(shù)據(jù)基本不怎么改變的情況。 偏好存儲:使用...
    戀空K閱讀 378評論 0 2
  • 概論 所謂的持久化退盯,就是將數(shù)據(jù)保存到硬盤中彼乌,使得在應(yīng)用程序或機(jī)器重啟后可以繼續(xù)訪問之前保存的數(shù)據(jù)。在iOS開發(fā)中渊迁,...
    Leeson1989閱讀 1,917評論 4 1