数据存储_FMDB数据库队列
一、代码示例
1.需要先导入FMDB框架和头文件,由于该框架依赖于libsqlite库,所以还应该导入该库。
2.代码如下:
1 // 2 // YYViewController.m 3 // 05-FMDB数据库队列 4 // 5 // Created by apple on 14-7-28. 6 // Copyright (c) 2014年 wendingding. All rights reserved. 7 // 8 9 #import "YYViewController.h" 10 #import "FMDB.h" 11 12 @interface YYViewController () 13 @property(nonatomic,strong)FMDatabaseQueue *queue; 14 @end 15 16 @implementation YYViewController 17 18 - (void)viewDidLoad 19 { 20 [super viewDidLoad]; 21 22 //1.获得数据库文件的路径 23 NSString *doc=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 24 NSString *fileName=[doc stringByAppendingPathComponent:@"person.sqlite"]; 25 26 //2.获得数据库队列 27 FMDatabaseQueue *queue=[FMDatabaseQueue databaseQueueWithPath:fileName]; 28 // FMDatabase *db=[FMDatabase databaseWithPath:fileName]; 29 30 //3.打开数据库 31 [queue inDatabase:^(FMDatabase *db) { 32 BOOL result=[db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL);"]; 33 if (result) { 34 NSLog(@"创表成功"); 35 }else 36 { 37 NSLog(@"创表失败"); 38 } 39 }]; 40 self.queue=queue; 41 42 } 43 44 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 45 { 46 //插入数据 47 // [self.queue inDatabase:^(FMDatabase *db) { 48 // [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @22]; 49 // }]; 50 51 //查询数据 52 [self.queue inDatabase:^(FMDatabase *db) { 53 // 1.执行查询语句 54 FMResultSet *resultSet = [db executeQuery:@"SELECT * FROM t_person"]; 55 56 // 2.遍历结果 57 while ([resultSet next]) { 58 int ID = [resultSet intForColumn:@"id"]; 59 NSString *name = [resultSet stringForColumn:@"name"]; 60 int age = [resultSet intForColumn:@"age"]; 61 NSLog(@"%d %@ %d", ID, name, age); 62 } 63 }]; 64 65 } 66 67 @end
先插入数据,之后查询结果,打印如下:
3.代码说明
1 //插入数据 2 [self.queue inDatabase:^(FMDatabase *db) { 3 [db beginTransaction]; 4 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @22]; 5 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @23]; 6 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @24]; 7 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @25]; 8 [db commit]; 9 }];
如果中途出现问题,那么会自动回滚(重新开始),也可以选择手动回滚。
1 //插入数据 2 [self.queue inDatabase:^(FMDatabase *db) { 3 [db beginTransaction]; 4 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @22]; 5 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @23]; 6 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @24]; 7 [db rollback]; 8 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @25]; 9 [db commit]; 10 }];
上面的代码。前三条插入语句是作废的。
事务处理的另一种方式:
1 [self.queue inTransaction:^(FMDatabase *db, BOOL *rollback) { 2 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @22]; 3 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @23]; 4 [db executeUpdate:@"INSERT INTO t_person (name, age) VALUES (?, ?);",@"wendingding", @24]; 5 }];
具体可以参考FMDB官方文档:
- FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
- [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]];
- }];
whoopsSomethingWrongHappened是什么鬼?????看一下下面的demo
#pragma mark - 数据存储文件的路径
- (NSString *)dbPathTest {
NSString *string = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *stringPath = [string stringByAppendingPathComponent:@"test.sqlite"];
NSLog(@"%@",stringPath);
return stringPath;
}
#pragma mark - 多线程操作数据库时,事务的处理方式
- (void)threadTransaction {
//创建队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self dbPathTest]];
__block BOOL whoopsSomethingWrongHappened = true;
//把任务包装到事务里
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTable values(?)",[NSNumber numberWithInt:1]];
whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTable values(?)",[NSNumber numberWithInt:2]];
whoopsSomethingWrongHappened &= [db executeUpdate:@"insert into myTabl values(?)",[NSNumber numberWithInt:3]];
//如果有错误 返回
if(!whoopsSomethingWrongHappened) {
*rollback = YES;
return;
}
NSLog(@"hello,yoowei");
}];
}
还可以看一下其他的demo中的写法:
- (void)saveChangesInBackground:(void (^)())complete {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:self.schema.storage];
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
@try {
for (FMDTObject *entry in self.dataArray) {
NSArray *array = [self getObjectValues:entry];
NSString *statement = nil;
if (self.relpace) {
statement = self.schema.statementReplace;
} else {
statement = self.schema.statementInsert;
}
[db executeUpdate:statement withArgumentsInArray:array];
}
}
@catch (NSException *exception) {
*rollback = YES;
}
[self.dataArray removeAllObjects];
if (complete) {
complete();
}
}];
});
}
- (void)threadNoTransaction {
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:[self dbPathTest]];
[queue inDatabase:^(FMDatabase *db) {
[db beginTransaction];
BOOL isRollBack = NO;
@try {
for (int i = 0; i<5; i++) {
NSString *roomID= [[NSString alloc] initWithFormat:@"roomid_%d",i];
NSString *sql= @"insert into myTable values(?)";
BOOL a = [db executeUpdate:sql,roomID];
if (!a) {
NSLog(@"插入失败1");
}
}
}
@catch (NSException *exception) {
isRollBack = YES;
[db rollback];
}
@finally {
if (!isRollBack) {
[db commit];
}
}
}];
}
参考链接:
http://www.cnblogs.com/wendingding/p/3873874.html
https://github.com/ccgus/fmdb