美文网首页
FMDB详解(v2.7)

FMDB详解(v2.7)

作者: 开发者老岳 | 来源:发表于2018-04-14 23:26 被阅读27次

包含仨主要类:
FMDatabaseFMResultSetFMDatabaseQueue

创建数据库

FMDatabase 是基于一个数据库文件的path创建的,该path有三种情况:

  • 文件路径。文件不已经存在,若不存在会在该路径下创建一个空数据库文件。
  • 空字符(@"")。此时会在临时目录创建一个空的数据库文件,当FMDatabase链接关闭时自动删除。
  • NULL。此时会在内存里创建一个空的数据库,统一链接关闭时删除。
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.db"];
FMDatabase *db = [FMDatabase databaseWithPath:path];

打开

操作数据库前,数据库必须是打开状态的。当空间不足或者没有权限的时候,就会打开失败。

if (![db open]) {
    db = nil;
    return;
}

Executing Updates

  • 数据库语句除了select的都可以用update,包括CREATE, UPDATE, INSERT, ALTER, COMMIT, BEGIN等。
  • Executing Updates返回一个布尔类型值表示成功与否,返回NO的话表示发生错误,错误原因可以从-lastErrorMessage-lastErrorCode方法里查找。

Executing Queries

  • 主要就是select的方法通过调用几个-executeQuery...方法。查询成功返回FMResultSet对象,失败返回nil,失败错误原因同样可以从-lastErrorMessage-lastErrorCode方法里查找。
  • 若结果有多个,需要遍历结果的话,一般需要用到while方法,如:
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
    //retrieve values for each record
}

结果只有一个的时候,也要调用next方法。如下:

FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
    int totalCount = [s intForColumnIndex:0];
}

FMResultSet有若干方法可用于解析返回的数据,如下:

  • - (int)intForColumn:(NSString*)columnName;
  • - (long)longForColumn:(NSString*)columnName;
  • - (BOOL)boolForColumn:(NSString*)columnName;
  • - (NSString*)stringForColumn:(NSString*)columnName;
  • - (NSDate*)dateForColumn:(NSString*)columnName;
  • - (id _Nullable)objectForColumn:(NSString*)columnName;
  • - (const unsigned char * _Nullable)UTF8StringForColumn:(NSString*)columnName;
  • ...
    这些方法里都有个对应的 ForColumnIndex:方法,如下:
    - (int)intForColumnIndex:(int)columnIdx;,这些都是基于Column在结果中的位置去查找,而不是其ColumnName
  • 一般不用自己去-close一个FMResultSet,因为在结果集(FMResultSet)被释放或者父数据库close时会自动 close

Closing

当执行完queries(查询)或updates(更新)数据库后,要手动-closeFMDatabase连接,释放相应的资源。

 [db close];

Transactions

FMDatabase can begin and commit a transaction by invoking one of the appropriate methods or executing a begin/end transaction statement.

多语句和批量处理(Multiple Statements and Batch Stuff)

可以通过调用FMDatabaseexecuteStatements:withResultBlock:方法来执行多条sql语句:

NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);"
                 "create table bulktest2 (id integer primary key autoincrement, y text);"
                 "create table bulktest3 (id integer primary key autoincrement, z text);"
                 "insert into bulktest1 (x) values ('XXX');"
                 "insert into bulktest2 (y) values ('YYY');"
                 "insert into bulktest3 (z) values ('ZZZ');";

success = [db executeStatements:sql];

sql = @"select count(*) as count from bulktest1;"
       "select count(*) as count from bulktest2;"
       "select count(*) as count from bulktest3;";

success = [self.db executeStatements:sql withResultBlock:^int(NSDictionary *dictionary) {
    NSInteger count = [dictionary[@"count"] integerValue];
    XCTAssertEqual(count, 1, @"expected one record for dictionary %@", dictionary);
    return 0;
}];

数据清理(Data Sanitization)

查询时问号?的使用:

NSInteger identifier = 42;
NSDate *date = [NSDate date];
NSString *comment = nil;

BOOL success = [db executeUpdate:@"INSERT INTO authors (identifier, date, comment) VALUES (?, ?, ?)", @(identifier), date, comment ?: [NSNull null]];
if (!success) {
    NSLog(@"error = %@", [db lastErrorMessage]);
}
  • Note: NSInteger应该转为NSNumber对象。同样,某条为空的时候,插入数据库的是[NSNull null]对象,本例中comment就用了?:方法处理的,非空就用comment,为空就用冒号后面的[NSNull null]

冒号的使用:

NSDictionary *arguments = @{@"name": name, @"date": date, @"comment": comment ?: [NSNull null]};
BOOL success = [db executeUpdate:@"INSERT INTO authors (name, date, comment) VALUES (:name, :date, :comment)" withParameterDictionary:arguments];
if (!success) {
    NSLog(@"error = %@", [db lastErrorMessage]);
}
  • 不要用 NSStringstringWithFormat:方法往sql语句里插入属性,要通过问号去插入。

FMDatabaseQueue 和线程安全

不要在多个线程里共享使用同一个FMDatabase的单例,因为会有线程安全的问题。多线程里要用FMDatabaseQueue,使用方法:

//创建队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
//使用
[queue inDatabase:^(FMDatabase *db) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];

    FMResultSet *rs = [db executeQuery:@"select * from foo"];
    while ([rs next]) {
        …
    }
}];

FMDataBaseQueue使用事务:

[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];

    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }

    // etc ...
}];

FMDatabaseQueue能保证在多线程里任务顺序的执行,而不会冲突。

Making custom sqlite functions, based on blocks.

You can do this! For an example, look for -makeFunctionNamed: in main.m

相关文章

  • FMDB详解(v2.7)

    包含仨主要类:FMDatabase、FMResultSet、FMDatabaseQueue 创建数据库 FMDat...

  • 常用第三方框架

    FMDB 数据库插件 SWTableViewCell FMDB v2.7 数据库第三方类 JGProgressHU...

  • iOS数据库之FMDB、Realm、WCDB

    1.引子FMDB FMDB详解FMDB的git链接 1.1 它基于SQLite 封装,对于有SQLite 和Obj...

  • 笔记-FMDB详解

    简介 SQLite 一个轻量级的关系型数据库,SQLite不区分大小写,但是也有注意的地方,GLOB和glob具有...

  • iOS FMDB使用详解

    什么是FMDB 很简单,一个iOS中SQLite API的封装库。 其他的巴拉巴拉一大堆总结下来就是: 1.是对l...

  • iOS FMDB库详解

    更新时间:2017-04-17 修改了代码的排版 前言(唠叨) 在网上搜FMDB的资料,要么是很精简的介绍(针对比...

  • iOS-FMDB详解及使用

    一 FMDB简介 什么是 FMDB FMDB 是 iOS 平台的 SQLite 数据库框架 FMDB 以 OC 的...

  • iOS开发·FMDB的使用与知识梳理

    一、FMDB的介绍二、FMDB的使用说明三、FMDB的创建和使用方法 一、FMDB的介绍 FMDB是构建在SQLi...

  • FFDB

    FMDB的使用 FMDBDemo 目录 1、FMDB介绍2、FMDB导入3、FMDB框架中重要的框架类3.1、FM...

  • iOS数据持久化——FMDB(对SQLite的轻量级封装)

    一、FMDB简介 FMDB是一种第三方的开源库(ccgus/fmdb · GitHub),FMDB就是对SQLit...

网友评论

      本文标题:FMDB详解(v2.7)

      本文链接:https://www.haomeiwen.com/subject/jazckftx.html