qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

          iOS開發(fā)之FMDB

            sqlite作為一個輕量級的數(shù)據(jù)庫,由于它占用的內(nèi)存很少,因此在很多的嵌入式設(shè)備中得到廣泛的使用。iOS的SDK很早就開始支持了SQLite,我們只需要加入 libsqlite3.dylib 以及引入 sqlite3.h 頭文件即可,但由于原生sqlite的API不是很友好,因此使用的話一般會對其做一層封裝,其中以開源的FMDB最為流行。
            FMDB主要的類
            1.FMDatabase – 表示一個單獨(dú)的SQLite數(shù)據(jù)庫。 用來執(zhí)行SQLite的命令。
            2.FMResultSet – 表示FMDatabase執(zhí)行查詢后結(jié)果集
            3.FMDatabaseQueue – 當(dāng)你在多線程中執(zhí)行操作,使用該類能確保線程安全。
            FMDB的使用
            數(shù)據(jù)庫的創(chuàng)建:
            創(chuàng)建FMDatabase對象時需要參數(shù)為SQLite數(shù)據(jù)庫文件路徑。該路徑可以是以下三種之一:
            1..文件路徑。該文件路徑無需真實(shí)存,如果不存在會自動創(chuàng)建。
            2..空字符串(@”")。表示會在臨時目錄創(chuàng)建一個臨時數(shù)據(jù)庫,當(dāng)FMDatabase 鏈接關(guān)閉時,文件也被刪除。
            3.NULL. 將創(chuàng)建一個內(nèi)存數(shù)據(jù)庫。同樣的,當(dāng)FMDatabase連接關(guān)閉時,數(shù)據(jù)會被銷毀。
            內(nèi)存數(shù)據(jù)庫:
            通常數(shù)據(jù)庫是存放在磁盤當(dāng)中的。然而我們也可以讓存放在內(nèi)存當(dāng)中的數(shù)據(jù)庫,內(nèi)存數(shù)據(jù)庫的優(yōu)點(diǎn)是對其操作的速度較快,畢竟訪問內(nèi)存的耗時低于訪問磁盤,但內(nèi)存數(shù)據(jù)庫有如下缺陷:由于內(nèi)存數(shù)據(jù)庫沒有被持久化,當(dāng)該數(shù)據(jù)庫被關(guān)閉后就會立刻消失,斷電或程序崩潰都會導(dǎo)致數(shù)據(jù)丟失;不支持讀寫互斥處理,需要自己手動添加鎖;無法被別的進(jìn)程訪問。
            臨時數(shù)據(jù)庫:
            臨時數(shù)據(jù)庫和內(nèi)存數(shù)據(jù)庫非常相似,兩個數(shù)據(jù)庫連接創(chuàng)建的臨時數(shù)據(jù)庫也是各自獨(dú)立的,在連接關(guān)閉后,臨時數(shù)據(jù)庫將自動消失,其底層文件也將被自動刪除。盡管磁盤文件被創(chuàng)建用于存儲臨時數(shù)據(jù)庫中的數(shù)據(jù)信息,但是實(shí)際上臨時數(shù)據(jù)庫也會和內(nèi)存數(shù)據(jù)庫一樣通常駐留在內(nèi)存中,唯一不同的是,當(dāng)臨時數(shù)據(jù)庫中數(shù)據(jù)量過大時,SQLite為了保證有更多的內(nèi)存可用于其它操作,因此會將臨時數(shù)據(jù)庫中的部分?jǐn)?shù)據(jù)寫到磁盤文件中,而內(nèi)存數(shù)據(jù)庫則始終會將數(shù)據(jù)存放在內(nèi)存中。
            創(chuàng)建數(shù)據(jù)庫:FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;
            在進(jìn)行數(shù)據(jù)庫的操作之前,必須要先把數(shù)據(jù)庫打開,如果資源或權(quán)限不足無法打開或創(chuàng)建數(shù)據(jù)庫,都會導(dǎo)致打開失敗。
            如下為創(chuàng)建和打開數(shù)據(jù)庫的示例:
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentDirectory = [paths objectAtIndex:0];
            //dbPath: 數(shù)據(jù)庫路徑,存放在Document中。
            NSString *dbPath = [documentDirectory stringByAppendingPathComponent:@"MYTest.db"];
            //創(chuàng)建數(shù)據(jù)庫實(shí)例 db  這里說明下:如果路徑中不存在"MYTest.db"的文件,sqlite會自動創(chuàng)建"MYTest.db"
            FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;
            if (![db open]) {
            NSLog(@"Could not open db.");
            return ;
            }
            更新操作
            一切不是SELECT命令都視為更新操作,包括CREATE, UPDATE, INSERT,ALTER,COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM和REPLACE等。
            創(chuàng)建表:
            [db executeUpdate:@"CREATE TABLE myTable (Name text,Age integer)"];
            插入
            [db executeUpdate:@"INSERT INTO myTable (Name,Age) VALUES (?,?)",@"jason",[NSNumber numberWithInt:20]];
            更新
            [db executeUpdate:@"UPDATE myTable SET Name = ? WHERE Name = ? ",@"john",@"jason"];.
            刪除
            [db executeUpdate:@"DELETE FROM myTable WHERE Name = ?",@"jason"];
            查詢操作
            SELECT命令就是查詢,執(zhí)行查詢的方法是以 -excuteQuery開頭的。執(zhí)行查詢時,如果成功返回FMResultSet對象, 錯誤返回nil. 讀取信息的時候需要用while循環(huán):
            FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
            while ([s next]) {
            //從每條記錄中提取信息
            }
            關(guān)閉數(shù)據(jù)庫
            當(dāng)使用完數(shù)據(jù)庫,你應(yīng)該 -close 來關(guān)閉數(shù)據(jù)庫連接來釋放SQLite使用的資源。
            [db close];
            參數(shù)
            通常情況下,你可以按照標(biāo)準(zhǔn)的SQL語句,用?表示執(zhí)行語句的參數(shù),如:
            INSERT INTO myTable VALUES (?, ?, ?)
            然后,可以我們可以調(diào)用executeUpdate方法來將?所指代的具體參數(shù)傳入,通常是用變長參數(shù)來傳遞進(jìn)去的,如下:
            NSString *sql = @"insert into myTable (name, password) values (?, ?)";
            [db executeUpdate:sql, user.name, user.password];
            這里需要注意的是,參數(shù)必須是NSObject的子類,所以象int,double,bool這種基本類型,需要進(jìn)行相應(yīng)的封裝
            [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

          多線程操作
            由于FMDatabase對象本身不是線程安全的,因此為了避免在多線程操作的時候出錯,需要使用 FMDatabaseQueue來執(zhí)行相關(guān)操作。只需要利用一個數(shù)據(jù)庫文件地址來初使化FMDatabaseQueue,然后傳入一個block到inDatabase中,即使是多個線程同時操作,該queue也會確保這些操作能按序進(jìn)行,保證線程安全。
            創(chuàng)建隊(duì)列:
            FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
            使用方法:
          [queue inDatabase:^(FMDatabase *db) {
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
          FMResultSet *rs = [db executeQuery:@"select * from foo"];
          while([rs next]) {
          }
          }];
            至于事務(wù)可以像這樣處理:
          [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
          if (somethingWrongHappened) {
          *rollback = YES;
          return;
          }
          // etc…
          [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
          }];

          posted on 2014-12-08 22:00 順其自然EVO 閱讀(1444) 評論(0)  編輯  收藏 所屬分類: 測試學(xué)習(xí)專欄數(shù)據(jù)庫

          <2014年12月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 蓝山县| 清涧县| 澄城县| 鄱阳县| 乌兰浩特市| 吐鲁番市| 惠州市| 新民市| 昌黎县| 南昌市| 南华县| 博罗县| 红安县| 颍上县| 丁青县| 云林县| 牟定县| 民权县| 突泉县| 平陆县| 合阳县| 新密市| 涞源县| 盐津县| 嘉定区| 大荔县| 长乐市| 江达县| 甘南县| 鹤山市| 明星| 开封县| 遂宁市| 呼伦贝尔市| 洛隆县| 靖边县| 昌江| 堆龙德庆县| 铜陵市| 龙泉市| 桐乡市|