FMDB:2-更新操作与查询操作
在FMDB中,把对数据库的操作合并为两类,第一类是查询操作,即使用SELECT语句执行的操作,查询操作的特点是会返回查询结果,继而对查询结果做进一步的处理;第二类是更新操作,凡是涉及到更新数据库存储内容的操作都属于更新操作,例如在SQL中的UPDATE语句、INSERT语句等。
更新操作
在SQL语句中,所有非SELECT语句的都可以看成是更新操作,包括CREATE、UPDATE、INSERT、ALTER、DELETE、DROP等语句。在FMDB中,提供了executeUpdate:方法用于执行更新操作,需要执行的SQL语句作为参数传入该方法中。
- (BOOL)executeUpdate:(NSString*)sql, ...;
执行更新语句会返回一个BOOL值。如果是YES则表示更新成功,如果是NO则表示更新失败。可以调用lastErrorMessage和lastErrorCode方法来获取失败的原因。
- (NSString*)lastErrorMessage;
- (int)lastErrorCode;
查询操作
在FMDB中,执行的SELECT语句对应查询操作。所有的查询操作可以通过executeQuery:方法来执行,并且查询结果会作为该方法的返回值。
- (FMResultSet *)executeQuery:(NSString*)sql, ...;
执行查询语句之后,如果成功会返回一个FMResultSet对象。如果失败会返回nil,我们同样可以调用lastErrorMessage和lastErrorCode方法来获取失败的原因。
为了遍历查询的结果集,需要使用while()循环。并且调用FMResultSet类的next方法,从一条记录移动到下一条记录。例如:
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
//可以获取到每条查询记录的值
}
FMResultSet有很多方法来获取对应的值,主要包括两类,第一类是通过列名获取对应的值,第二类是通过列序号获取对应的值。例如,FMResultSet.h中提供了如下根据列名获取数值的方法:
- intForColumn:
- longForColumn:
- longLongIntForColumn:
- boolForColumn:
- doubleForColumn:
- stringForColumn:
- dateForColumn:
- dataForColumn:
- dataNoCopyForColumn:
- UTF8StringForColumnName:
- objectForColumnName:
同样也有{type}ForColumnIndex:方法来根据列序号获取不同的值。这些方法能通过位置,而不是通过列名来获取相对应的值。
通常来说我们不用手动调用FMResultSet的close方法。FMResultSet对象销毁或者数据库关闭时会自动调用FMResultSet的-close方法。
执行多条语句
当我们需要执行多条SQL语句时,FMDB也为我们提供了快捷方法,并不需要一条一条的执行。可以通过FMDatabase类中的executeStatements:方法来执行多条语句。
- (BOOL)executeStatements:(NSString *)sql;
- (BOOL)executeStatements:(NSString *)sql withResultBlock:(FMDBExecuteStatementsCallbackBlock)block;
下方的示例代码中,我们把多条SQL语句都封装在一个NSString类型的对象中执行。
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;
}];
SQL语句格式处理
在编写SQL语句时不必手动去拼接,可以使用标准的SQLite绑定语法:
INSERT INTO myTable VALUES (?, ?, ?, ?)
这样拼接SQL语句会更安全。?表示一个占位符,会被后续传进来的值所替代。所有的执行方法都接受一组参数(比如NSArray,NSDictionary或者va_list),然后会做一些适当的转义。
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]);
}
注意:替换?的参数需要是对象,不可以是值类型。比如NSInteger需要变成NSNumber, NULL需要变成[NSNULL null]。
示例代码
最后编辑时间为: September 22nd , 2017 at 01:27 am
本文由 99ios 创作,转载请注明出处