zoukankan      html  css  js  c++  java
  • iOS开发之FMDB

      sqlite作为一个轻量级的数据库,由于它占用的内存很少,因此在很多的嵌入式设备中得到广泛的使用。iOS的SDK很早就开始支持了SQLite,我们只需要加入 libsqlite3.dylib 以及引入 sqlite3.h 头文件即可,但由于原生sqlite的API不是很友好,因此使用的话一般会对其做一层封装,其中以开源的FMDB最为流行。

    FMDB主要的类

    1.FMDatabase – 表示一个单独的SQLite数据库。 用来执行SQLite的命令。

    2.FMResultSet – 表示FMDatabase执行查询后结果集

    3.FMDatabaseQueue – 当你在多线程中执行操作,使用该类能确保线程安全。

     

    FMDB的使用

    数据库的创建

    创建FMDatabase对象时需要参数为SQLite数据库文件路径。该路径可以是以下三种之一:

    1..文件路径。该文件路径无需真实存,如果不存在会自动创建。

    2..空字符串(@”")。表示会在临时目录创建一个临时数据库,当FMDatabase 链接关闭时,文件也被删除。

    3.NULL. 将创建一个内存数据库。同样的,当FMDatabase连接关闭时,数据会被销毁。

    内存数据库:

      通常数据库是存放在磁盘当中的。然而我们也可以让存放在内存当中的数据库,内存数据库的优点是对其操作的速度较快,毕竟访问内存的耗时低于访问磁盘,但内存数据库有如下缺陷:由于内存数据库没有被持久化,当该数据库被关闭后就会立刻消失,断电或程序崩溃都会导致数据丢失;不支持读写互斥处理,需要自己手动添加锁;无法被别的进程访问。

    临时数据库:

      临时数据库和内存数据库非常相似,两个数据库连接创建的临时数据库也是各自独立的,在连接关闭后,临时数据库将自动消失,其底层文件也将被自动删除。尽管磁盘文件被创建用于存储临时数据库中的数据信息,但是实际上临时数据库也会和内存数据库一样通常驻留在内存中,唯一不同的是,当临时数据库中数据量过大时,SQLite为了保证有更多的内存可用于其它操作,因此会将临时数据库中的部分数据写到磁盘文件中,而内存数据库则始终会将数据存放在内存中。

     

    创建数据库:FMDatabase *db= [FMDatabase databaseWithPath:dbPath] ;

    在进行数据库的操作之前,必须要先把数据库打开,如果资源或权限不足无法打开或创建数据库,都会导致打开失败。

    如下为创建和打开数据库的示例:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = [paths objectAtIndex:0];
    
    //dbPath: 数据库路径,存放在Document中。
    NSString *dbPath = [documentDirectory stringByAppendingPathComponent:@"MYTest.db"];
    
    //创建数据库实例 db  这里说明下:如果路径中不存在"MYTest.db"的文件,sqlite会自动创建"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等。

     创建表:

    [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命令就是查询,执行查询的方法是以 -excuteQuery开头的。执行查询时,如果成功返回FMResultSet对象, 错误返回nil. 读取信息的时候需要用while循环:

    FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];   
    while ([s next]) {   
        //从每条记录中提取信息
    
    }   

     

    关闭数据库

    当使用完数据库,你应该 -close 来关闭数据库连接来释放SQLite使用的资源。

     [db close];  

    参数

    通常情况下,你可以按照标准的SQL语句,用?表示执行语句的参数,如:

    INSERT INTO myTable VALUES (?, ?, ?)

    然后,可以我们可以调用executeUpdate方法来将?所指代的具体参数传入,通常是用变长参数来传递进去的,如下:

    NSString *sql = @"insert into myTable (name, password) values (?, ?)";
    [db executeUpdate:sql, user.name, user.password];

    这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要进行相应的封装

    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

     

    多线程操作

      由于FMDatabase对象本身不是线程安全的,因此为了避免在多线程操作的时候出错,需要使用 FMDatabaseQueue来执行相关操作。只需要利用一个数据库文件地址来初使化FMDatabaseQueue,然后传入一个block到inDatabase中,即使是多个线程同时操作,该queue也会确保这些操作能按序进行,保证线程安全。

    创建队列:

    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]]; }];
  • 相关阅读:
    bt5设置IP
    flyCoding
    [Cocoa][译]苹果 Cocoa 编码规范中文版
    [BZOJ4569] [Scoi2016]萌萌哒
    BZOJ4899]记忆的轮廓
    [BZOJ1701] [Usaco2007 Jan]Cow School牛学校
    [Poi2011]Lightning Conductor
    [BZOJ4709] [Jsoi2011] 柠檬
    决策单调性优化dp 专题练习
    2369. 区间
  • 原文地址:https://www.cnblogs.com/hello-LJ/p/4028509.html
Copyright © 2011-2022 走看看