FMDB笔记
Git上的官方文档翻译
1. Usage
FMDB中有三个主要的类:
- FMDatabase - 表示一个单独的 SQLite 数据库, 用来执行 SQL 语句
- FMResultSet - FMDataBase执行了查询以后用来显示结果的类
- FMDatabaseQueue - 如果你以多线程的方式进行一些查询操作或者更新操作, 那么你可以用这个类, 后面的 “线程安全” 部分对此有详细描述
2. 创建数据库
一个 FMDatabase 可以通过一个 SQLite 数据库文件的路径创建. 这种路径可以是以下三种之一:
- 一个文件的系统路径. 文件可以不必要存在于硬盘(磁盘)中. 如果不存在, 就会创建一个.
- 一个空路径( @“”). 这时候会在一个临时位置创建一个空的数据库. 当 FMDataBase 的连接被关闭的时候, 这个数据库就会被删除掉.
- NULL. 这时候会创建一个内存内的数据库. 这个数据库也会在 FMDataBase 连接被关闭的时候销毁掉.
(想获取更多关于临时数据库和内存内数据的信息, 可以在这个关于 SQLite 的课题的文档中获取到: http://www.sqlite.org/inmemorydb.html)
FMDatabase *db = [FMDatabase databaseWithPath: @"/tmp/tmp.db" ];
打开数据库
数据库首先得打开才能和用户进行交互. 资源问题或者权限问题都会导致打开或者创建数据库失败
if (![db open]) {
[db release\\];
return;
}
更新操作
任何一种不属于 SELECT 的 SQL 语句都可以称之为一个 Update. Update 包括 CREATE, UPDATE, INSERT, ALTER, COMMIT, BEGIN, DETACH, DELETE, DROP, END, EXPLAIN, VACUUM, 和 REPLACE 语句(还有更多). 一般来讲, 如果你的 SQL 语句没有以 SELECT 开头, 那么就属于 Update 语句
执行一个 Update 只会返回一个值, 一个 BOOL 值. 返回的是 YES 代表着 Update 操作执行成功, 返回值为 NO 说明发生了一些错误. 你可能需要使用 -lastErrorMessage
和 -lastErrorCode
方法来获取更多的消息
查询操作
一条 SELECT 语句就是一个查询可以通过使用 -executeQuery…
方法来执行查询
如果查询成功, 就会返回一个 FMResultSet 对象, 失败则会返回 nil. 想要知道查询是为什么失败, 你应该使用 -lastErrorMessage
和 -lastErrorCode
这两个方法
使用 while()
循环来重复获取查询结果. 你也可能需要使用 “ step” 从一个 record 跳转到另一个 record. 在 FMDB 下, 你可以很容易的通过以下代码实现
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
//retrieve values for each record
}
如果你想获取到查询到结果(返回值)— 就算你只是想拿到其中一个 — 你也必须要先调用 - [FMResultSet next]
FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
int totalCount = [s intForColumnIndex:0];
}
FMResultSet 拥有很多以各种数据形式来获取数据的方法:
- intForColumn
- longForColumn
- longLongIntForColumn
- boolForColumn
- doubleForColumn
- stringForColumn
- dateForColumn
- dataForColumn
- dataNoCopyForColumn
- UTF8StringForColumnName
- objectForColumnName
上面的每一个方法都有一个对应的 {type}ForColumnIndex:
变体来获取查询返回的column中对应的位置的数据, (index)正好与上面的column’name的相反
需要注意的是, 你不需要亲自去 -close 一个 FMResultSet, 当 result set 被 dealloc 了或者它的父级数据库被关闭的时候其实就已经被关闭了
数据库关闭
当你执行完一次查询以后并且在数据库那边进行了更新, 你应该调用 -close 来关闭 FMDataBase 连接, 接着 SQLite 就会抛弃(?)掉在之前操作过程所请求的所有资源
[db close];
事务
FMDataBase 可以通过调用合适的方法或者执行一个 开始/结束 transaction 语句来开始和提交一个 transaction
多个操作
通过使用 FMDataBase 的 executeStatements: withResultBlock: 以字符串的形式来一次性执行多个操作
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;
}];
数据净化
当你向 FMDB 提交一个 SQL 操作的时候, 不要试图在插入操作之前”净化” 任何数值. 相反, 你应该使用标准的 SQLite 绑定语法:
INSERT INTO myTable VALUES (?, ?, ?, ?)
SQLite 会自动把 “?” 识别为插入操作的数值占位符.™