<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    iOS開發(fā)之FMDB

      sqlite作為一個輕量級的數(shù)據(jù)庫,由于它占用的內存很少,因此在很多的嵌入式設備中得到廣泛的使用。iOS的SDK很早就開始支持了SQLite,我們只需要加入 libsqlite3.dylib 以及引入 sqlite3.h 頭文件即可,但由于原生sqlite的API不是很友好,因此使用的話一般會對其做一層封裝,其中以開源的FMDB最為流行。
      FMDB主要的類
      1.FMDatabase – 表示一個單獨的SQLite數(shù)據(jù)庫。 用來執(zhí)行SQLite的命令。
      2.FMResultSet – 表示FMDatabase執(zhí)行查詢后結果集
      3.FMDatabaseQueue – 當你在多線程中執(zhí)行操作,使用該類能確保線程安全。
      FMDB的使用
      數(shù)據(jù)庫的創(chuàng)建:
      創(chuàng)建FMDatabase對象時需要參數(shù)為SQLite數(shù)據(jù)庫文件路徑。該路徑可以是以下三種之一:
      1..文件路徑。該文件路徑無需真實存,如果不存在會自動創(chuàng)建。
      2..空字符串(@”")。表示會在臨時目錄創(chuàng)建一個臨時數(shù)據(jù)庫,當FMDatabase 鏈接關閉時,文件也被刪除。
      3.NULL. 將創(chuàng)建一個內存數(shù)據(jù)庫。同樣的,當FMDatabase連接關閉時,數(shù)據(jù)會被銷毀。
      內存數(shù)據(jù)庫:
      通常數(shù)據(jù)庫是存放在磁盤當中的。然而我們也可以讓存放在內存當中的數(shù)據(jù)庫,內存數(shù)據(jù)庫的優(yōu)點是對其操作的速度較快,畢竟訪問內存的耗時低于訪問磁盤,但內存數(shù)據(jù)庫有如下缺陷:由于內存數(shù)據(jù)庫沒有被持久化,當該數(shù)據(jù)庫被關閉后就會立刻消失,斷電或程序崩潰都會導致數(shù)據(jù)丟失;不支持讀寫互斥處理,需要自己手動添加鎖;無法被別的進程訪問。
      臨時數(shù)據(jù)庫:
      臨時數(shù)據(jù)庫和內存數(shù)據(jù)庫非常相似,兩個數(shù)據(jù)庫連接創(chuàng)建的臨時數(shù)據(jù)庫也是各自獨立的,在連接關閉后,臨時數(shù)據(jù)庫將自動消失,其底層文件也將被自動刪除。盡管磁盤文件被創(chuàng)建用于存儲臨時數(shù)據(jù)庫中的數(shù)據(jù)信息,但是實際上臨時數(shù)據(jù)庫也會和內存數(shù)據(jù)庫一樣通常駐留在內存中,唯一不同的是,當臨時數(shù)據(jù)庫中數(shù)據(jù)量過大時,SQLite為了保證有更多的內存可用于其它操作,因此會將臨時數(shù)據(jù)庫中的部分數(shù)據(jù)寫到磁盤文件中,而內存數(shù)據(jù)庫則始終會將數(shù)據(jù)存放在內存中。
      創(chuàng)建數(shù)據(jù)庫:FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;
      在進行數(shù)據(jù)庫的操作之前,必須要先把數(shù)據(jù)庫打開,如果資源或權限不足無法打開或創(chuàng)建數(shù)據(jù)庫,都會導致打開失敗。
      如下為創(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ù)庫實例 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]) {
      //從每條記錄中提取信息
      }
      關閉數(shù)據(jù)庫
      當使用完數(shù)據(jù)庫,你應該 -close 來關閉數(shù)據(jù)庫連接來釋放SQLite使用的資源。
      [db close];
      參數(shù)
      通常情況下,你可以按照標準的SQL語句,用?表示執(zhí)行語句的參數(shù),如:
      INSERT INTO myTable VALUES (?, ?, ?)
      然后,可以我們可以調用executeUpdate方法來將?所指代的具體參數(shù)傳入,通常是用變長參數(shù)來傳遞進去的,如下:
      NSString *sql = @"insert into myTable (name, password) values (?, ?)";
      [db executeUpdate:sql, user.name, user.password];
      這里需要注意的是,參數(shù)必須是NSObject的子類,所以象int,double,bool這種基本類型,需要進行相應的封裝
      [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

    多線程操作
      由于FMDatabase對象本身不是線程安全的,因此為了避免在多線程操作的時候出錯,需要使用 FMDatabaseQueue來執(zhí)行相關操作。只需要利用一個數(shù)據(jù)庫文件地址來初使化FMDatabaseQueue,然后傳入一個block到inDatabase中,即使是多個線程同時操作,該queue也會確保這些操作能按序進行,保證線程安全。
      創(chuàng)建隊列:
      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]) {
    }
    }];
      至于事務可以像這樣處理:
    [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 閱讀(1441) 評論(0)  編輯  收藏 所屬分類: 測試學習專欄數(shù)據(jù)庫

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

    導航

    統(tǒng)計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲性线免费观看视频成熟 | 亚洲大成色www永久网站| 亚洲人成伊人成综合网久久久| 成人免费的性色视频| 免费成人在线电影| 99在线观看视频免费| 久久免费视频观看| 嫖丰满老熟妇AAAA片免费看| 四虎影院免费在线播放| 亚洲国产成人久久精品99| 亚洲va久久久噜噜噜久久狠狠 | 爽爽爽爽爽爽爽成人免费观看| 在线观看亚洲免费视频| 人人狠狠综合久久亚洲| 国产无遮挡色视频免费观看性色| 久久久久国色av免费看| 啦啦啦在线免费视频| 亚洲色无码一区二区三区| 亚洲国产精品线观看不卡| 亚洲影视一区二区| 污网站免费在线观看| 久久综合国产乱子伦精品免费| 日韩中文无码有码免费视频| 日韩免费高清视频网站| 亚洲精品无码国产| 中文字幕乱码亚洲无线三区| 成人免费无码H在线观看不卡| 免费看h片的网站| 国产成人精品亚洲精品| 亚洲日韩乱码中文无码蜜桃| 免费无码AV一区二区| 69堂人成无码免费视频果冻传媒 | 免费三级毛片电影片| 久久精品亚洲男人的天堂| 亚洲一级毛片在线播放| 亚洲熟女综合一区二区三区| 亚洲成a∧人片在线观看无码| 野花香高清视频在线观看免费| 午夜免费不卡毛片完整版| 亚洲成网777777国产精品| 亚洲国产福利精品一区二区|