FMDB的优点和简介网上已经很多了,这里只是对其使用方法做一个简单的总结。总结的大部分知识点都是来自于github:https://github.com/ccgus/fmdb
一、FMDB中主要有三个类:
1、FMDatabase -> 表示单个SQLite数据库。 用于执行SQL语句。
2、FMResultSet ->表示对FMDatabase执行查询的结果。
3、FMDatabaseQueue -> 多个线程上执行查询和更新的工作。
二、创建数据库表
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.db"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
#上边代码中的NSTemporaryDirectory(),括号中是写指定创建表的路径。
示例:NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"tmp.db"];
FMDatabase *db = [FMDatabase databaseWithPath:path];
&文件的路径有三种情况:
(1)、文件的具体路径。如果不存在会自动创建。
(2)、一个空的字符串 @""。会在临时位置创建一个空的数据库,当 FMDatabase 连接关闭时,该数据库会被删除。**
(3)、nil。会在内存中创建一个数据库,当 FMDatabase 连接关闭时,该数据库会被销毁。
二、数据库的使用
注意:数据库必须是打开状态,才能去进行相应的工作。如果创建数据库的条件不满足或者数据库没有打开,数据库会打开失败。
if (![db open]) { db = nil; return;}
1)、执行更新
**SQL语句中基本上,如果您的SQL语句不是以`SELECT`开头,它就是是一个符合更新条件的update语句。 通过`executeUpdate:`方法执行更新操作。这包括CREATE,UPDATE,INSERT,ALTER,COMMIT,BEGIN,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM和REPLACE语句(以及更多)。**
**执行更新语句后会返回一个 BOOL 值,返回 YES 表示执行更新语句成功,返回 NO 表示出现错误。如果返回NO可以通过调用以下方法获取更多错误信息。
-lastErrorMessage
-lastErrorCode **
使用executeUpdate:方法执行更新操作,该方法具体如下:
- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql
withArgumentsInArray:(NSArray *)arguments
2)、执行查询
通过调用以下方法执行SELECT
语句进行查询操作
- executeQuery ...方法执行,该方法具体如下:
- (FMResultSet)executeQuery:(NSString)sql, ...
- (FMResultSet)executeQueryWithFormat:(NSString)format,...
- (FMResultSet)executeQuery:(NSString)sqlwithArgumentsInArray:(NSArray*)arguments
如果成功,执行查询返回FMResultSet对象,失败时返回nil。 如果失败可以调用以下方法来确定查询失败的原因。
-lastErrorMessage
-lastErrorCode
**为了遍历查询结果,在 FMDB 中,可以使用 while()循环,然后逐条记录查看。**
#示例:
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];while ([s next]) {每条记录的检索值}
**即使只需要获取一个数据,也还是必须在访问查询结果前调用 **
-[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: 变体,是基于列的位置来查询数据。
3)、关闭数据库
**1、通常情况下,一个 FMResultSet 没有必要手动 -close,因为结果集合 (result set) 被释放或者源数据库关闭会自动关闭。
2、如果当您完成对数据库的查询和更新后,需要手动关闭FMDatabase连接的话,就调用[db close];关闭**
三、FMDB中提供了事务操作的功能
**对于事务的理解,网上搜了一下个人感觉这句话还是比较容易理解的,所以就搬过来了。
事务就是是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。
个人理解,事务的优势主要体现在对数据库进行多次重复操作和多次复合操作上边。采用FMDB中提供的事务操作可以提高我们使用数据库的效率。以下就是FMDB中对事务操作的相关介绍。**
FMDatabase可以通过调用适当的方法或者执行begin transaction
和end transaction
语句来开始和提交事务。
1)、多个语句和批量处理
**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;}];
数据处理
如果往数据库插入数据的时候,不确定的值可以通过标准的SQLite绑定语法来进行操作。下面的SQLite语句中'?' 字符为占位符, 执行方法可以接受可变数量的参数(例如NSArray,NSDictionary或va_list),这些参数为您正确转义。
1)、使用“?”作为占位符进行插入操作
INSERT INTO myTable VALUES (?, ?, ?, ?)
示例:
NSInteger identifier = 42;
NSString *name = @"Liam O'Flaherty (\"the famous Irish author\")";
NSDate *date = [NSDate date];
NSString *comment = nil;
BOOL success = [db executeUpdate:@"INSERT INTO authors (identifier, name, date, comment) VALUES (?, ?, ?, ?)", @(identifier), name, date, comment ?: [NSNull null]];
if (!success) { NSLog(@"error = %@", [db lastErrorMessage]);}
2)、使用命名参数语法:
INSERT INTO authors (identifier, name, date, comment) VALUES (:identifier, :name, :date, :comment)
注意:参数必须以冒号开头。 SQLite本身支持其他字符,但在内部,字典键前面加上冒号,不要在字典键中包含冒号。
示例
NSDictionary *arguments = @{@"identifier": @(identifier), @"name": name, @"date": date, @"comment": comment ?: [NSNull null]};
BOOL success = [db executeUpdate:@"INSERT INTO authors (identifier, name, date, comment) VALUES (:identifier, :name, :date, :comment)" withParameterDictionary:arguments];
if (!success) { NSLog(@"error = %@", [db lastErrorMessage]);}