上周四、周五在忙公司的事情和炒股,没来得及更新博客,这周就补一下,学习总结下FMDB。
FMDB是对sqlite的封装,特别是在多线程情况下,使用sqlite是非常麻烦,而使用FMDB相对简单,下面是使用FMDatabase和FMDatabasequeue的代码例子
// // ViewController.m // FMDBDemo // // Created by cyw on 15-4-26. // Copyright (c) 2015年 cyw. All rights reserved. // #import "ViewController.h" #import "FMDB.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // FMDB常用三个类: // 1.FMDatabase :单一的sqlite数据库,用于执行sql语句 // 2.FMDatabaseQueue:多线程下执行sql语句 // 3.FMResultSet:sql语句的结果集 // 1.数据库文件路径 NSString *path=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *filePath=[path stringByAppendingPathComponent:@"cyw.sqlite"]; NSLog(@"%@",filePath); // 创建FMDB对象 // 参数有3中情况: // 1.文件路径 文件不存在自动创建 // 2.nil 会创建内存中的临时数据库,当FMDatabase关闭时,自动销毁 // 3.@"" 会在临时目录创建空数据库,关闭时销毁 // FMDatabase *db=[[FMDatabase alloc]initWithPath:filePath]; // FMDatabase *bd=[FMDatabase databaseWithPath:filePath]; //打开数据库 // if ([db open]) { // //新建数据库 // [self createTable:db]; // // //插入数据 // [self insertData:db]; // //查询数据 // [self selectData:db]; // [db close]; // } // 数据库有锁和事务,在FMDB中可以用FMDatabaseQueue来实现 // 锁主要解决多线程的问题 事务算是加了一个隐式锁 //创建数据库队列 FMDatabaseQueue *queue=[FMDatabaseQueue databaseQueueWithPath:filePath]; // [self queueSelect:queue]; // [self queueTransaction:queue]; [self queueIntranscation:queue]; } -(BOOL)createTable:(FMDatabase*)db { //此两个sql一起执行报错 //create table if not exists P_Class (CId integer primary key ,CName varchar(20)); NSString *strsql=@"create table if not exists Person(id integer primary key autoincrement ,age integer not null,name text not null,photo blob,registerTime DATETIME DEFAULT (datetime(CURRENT_TIMESTAMP,'localtime')),sex char(1) default '0',money numeric(10,2),classId integer,constraint fk_Person_class foreign key (classId) references P_Class (CId));"; // FMDatabase中更新操作都是使用executeUpdate方法 查询使用executeQuery方法 BOOL result= [db executeUpdate:strsql]; if (result) { NSLog(@"数据库创建成功"); } else { NSLog(@"数据库创建失败"); } return result; } -(void)insertData:(FMDatabase*)db { [db executeUpdate:@"delete from person"]; //executeUpdate方法的不同参数 // [db executeUpdate:@"insert into P_Class(CId,CName) values(?,?);" withArgumentsInArray:@[@1001,@"软件工程"]]; //注意加@ [db executeUpdate:@"insert into person(name,age,money,classId) values(?,?,?,?);",@"cuiyw",@24,@200.3,@1001]; [db executeUpdateWithFormat:@"insert into Person(name,age,money,classId) values(%@,%d,%f,%d)",@"cyw",23,210.9,1001]; } -(void)selectData:(FMDatabase*)db { // 查询数据 NSString *strsql=@"select id,name,age,money from Person"; // FMResultSet返回结果集 FMResultSet *set=[db executeQuery:strsql]; while ([set next]) { int pid=[set intForColumn:@"id"]; NSString *name=[set stringForColumnIndex:1]; int age=[set intForColumn:@"age"]; float money=[set doubleForColumnIndex:3]; NSLog(@"%d %@ %d %f",pid,name,age,money); } NSString *strsql1=@"select CId,CName from P_Class"; // FMResultSet返回结果集 FMResultSet *set1=[db executeQuery:strsql1]; while ([set1 next]) { NSString *name=[set1 stringForColumnIndex:1]; int age=[set1 intForColumn:@"CId"]; // float money=[set doubleForColumnIndex:2]; NSLog(@"%@ %d ",name,age); } } -(void)queueSelect:(FMDatabaseQueue*)queue { //打开数据库 [queue inDatabase:^(FMDatabase *db) { [self selectData:db]; }]; } //事务的两种写法 -(void)queueTransaction:(FMDatabaseQueue*)queue { [queue inDatabase:^(FMDatabase *db) { [self selectData:db]; [db beginTransaction]; [db executeUpdate:@"update Person set money=money+20.0 where id=4"]; [db executeUpdate:@"update Person set money=money-20.0 where id=3"]; [db commit]; [self selectData:db]; }]; } -(void)queueIntranscation:(FMDatabaseQueue*)queue { [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [self selectData:db]; [db executeUpdate:@"update Person set money=money+20.0 where id=4"]; [db executeUpdate:@"update Person set money=money-20.0 where id=3"]; [self selectData:db]; }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end