• 数据库操作(使用FMDB)


    SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。但是,原生的SQLite API在使用上相当不友好,在使用时,非常不便。于是,开源社区中就出现了一系列将SQLite API进行封装的库,而FMDB (https://github.com/ccgus/fmdb) 则是开源社区中的优秀者。

    FMDB使用示例:

    NSString* docsdir = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    NSString* dbpath = [docsdir stringByAppendingPathComponent:@"user.sqlite"];
    
    FMDatabase* db = [FMDatabase databaseWithPath:dbpath];
    // 打开数据库
    [db open];
    // 查询后的结果
    FMResultSet *rs = [db executeQuery:@"select * from people"];
    while ([rs next]) {
        NSLog(@"%@ %@",
            [rs stringForColumn:@"firstname"],
            [rs stringForColumn:@"lastname"]);
    }
    [db close];

    使用FMDB后的数据库代码清晰明了,比原生的API优雅多了。另外,FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。

    使用说明:

    该使用说明主要翻译自fmdb的github项目说明文档: https://github.com/ccgus/fmdb

    引入相关文件

    首先将FMDB从github上clone下来,然后将以下文件copy到你的工程中:

    FMDatabase.h
    FMDatabase.m
    FMDatabaseAdditions.h
    FMDatabaseAdditions.m
    FMDatabasePool.h
    FMDatabasePool.m
    FMDatabaseQueue.h
    FMDatabaseQueue.m
    FMResultSet.h
    FMResultSet.m

    建立数据库

    建立数据库只需要如下一行即可,当该文件不存在时,fmdb会自己创建一个如果你传入的参数是空串:@“” ,则fmdb会在临时文件目录下创建这个数据库,如果你传入的参数是 NULL,则它会建立一个在内存中的数据库。

    FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];

    打开数据库

    使用如下语句,如果打开失败,可能是权限不足或者资源不足。通常打开完操作操作后,需要调用close方法来关闭数据库。

    if (![db open]) {
        // error 
        return;
    }
    // some operation
    
    [db close];

    执行更新操作

    除了Select操作之外,其它的都是更新操作。更新操作使用如下方法,如果有错误,可以用error参数中获得。

    [FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:]

    执行查询操作

    查询操作示例如下。注意:即使操作结果只有一行,也需要先调用FMResultSet的next方法。

    MResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
    while ([s next]) {
        //retrieve values for each record
    }
    FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
    if ([s next]) {
        int totalCount = [s intForColumnIndex:0];
    }

    FMDB提供如下多个方法来获取不同类型的数据:

    intForColumn:
    longForColumn:
    longLongIntForColumn:
    boolForColumn:
    doubleForColumn:
    stringForColumn:
    dateForColumn:
    dataForColumn:
    dataNoCopyForColumn:
    UTF8StringForColumnIndex:
    objectForColumn:

    通常情况下,你并不需要关闭FMResultSet,因为相关的数据库关闭时,FMResultSet也会被自动关闭。

    数据参数

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

    1
    
    INSERT INTO myTable VALUES (?, ?, ?)
    

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

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

    这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要封装成对应的包装类才行,如下所示:

    1
    2
    3
    4
    
    // 错误,42不能作为参数
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];
    // 正确,将42封装成 NSNumber 类
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

    线程安全

    如果我们的app需要多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 切记不能在多个线程中共同一个FMDatabase对象并且在多个线程中同时使用,这个类本身不是线程安全的,这样使用会造成数据混乱等问题。

    使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理。

    
    

     // 1.获得数据库文件的路径

    
    

        NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

        NSString *filename = [doc stringByAppendingPathComponent:@"persons.sqlite"];


    //
    创建,最好放在一个单例的类中 filename:数据库文件地址 FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:filename]; // 使用 [queue inDatabase:^(FMDatabase *db) { [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]]; 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 (whoopsSomethingWrongHappened) { *rollback = YES; return; } // etc… [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];

    为了查看Sqlite中的数据,一个好的图形化界面的数据库管理程序是必不可少的。mysql有phpMyAdmin,那么sqlite呢?

    有部分人使用的是Firefox的一个名为SQLite Manager的插件,安装此插件后,可以直接打开后缀名为sqlite的数据库文件。SQLite Manager提供一个图形化的界面来执行数据查询或更改操作。如下图所示:

    我使用的是:Navicat Premium

    总结

    FMDB将SQLite API进行了很友好的封装,使用上非常方便,对于那些使用纯Sqlite API来进行数据库操作的app,可以考虑将其迁移到基于FMDB上,这对于以后数据库相关功能的开发维护,可以提高不少效率。

  • 相关阅读:
    mac 10.15.7 修改PATH
    oc 属性类型一般用法
    ubuntu解压zip文件名乱码
    telnet 退出
    docker 根据容器创建镜像
    mac android adb device 没有显示设备
    Yii2 查看所有的别名 alias
    Yii2 App Advanced 添加 .gitignore
    ubuntu 18.04 搜狗突然就提示乱码
    An error occured while deploying the file. This probably means that the app contains ARM native code and your Genymotion device cannot run ARM instructions. You should either build your native code to
  • 原文地址:https://www.cnblogs.com/Fc-ios/p/3896117.html
Copyright © 2020-2023  润新知