数据持久化之FMDB简单使用
来源:互联网 发布:公民网络身份识别系统 编辑:程序博客网 时间:2024/06/05 08:41
使用第三方库FMDB
1.创建.db文件,并取得路径
-(NSString *)getDBPath{ NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"]; return dbPath;}
2.创建表格,保存数据库
先要打开数据库,创建表,向表中插入数据,再执行更新操作,然后关闭数据库
- (IBAction)saveButtonClicked:(id)sender { //获取Document文件夹下的数据库文件,没有则创建 NSString *dbPath = [self getDBPath]; FMDatabase *database = [FMDatabase databaseWithPath:dbPath]; if (![database open]) { NSLog(@"Open database failed"); return; } //创建表 [database executeUpdate:@"create table user (name text,gender text,age integer)"]; //插入数据 BOOL insert = [database executeUpdate:@"insert into user values (?,?,?)", self.nameTextField.text,self.genderTextField.text,self.ageTextField.text]; if (insert) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"保存成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } // 关闭数据库连接 [database close];}
3.查询操作
先打开数据库,执行查询,再关闭数据库
NSString *dbPath = [self getDBPath]; FMDatabase *database = [FMDatabase databaseWithPath:dbPath]; if (![database open]) { return; } //不需要像Android中那样关闭Cursor关闭FMResultSet,因为相关的数据库关闭时,FMResultSet也会被自动关闭 FMResultSet *resultSet = [database executeQuery:@"select * from user"];
// 条件查询
<p style="margin-top: 0px; margin-bottom: 0px; font-size: 13px; font-family: Menlo;"><span style="color:#424242;"> // </span><strong>FMResultSet</strong> *resultSet = [database <strong>executeQuery</strong>:@"select * from user where name = ?",@"welfred"];</p> while ([resultSet next]) { NSString *name = [resultSet stringForColumn:@"name"]; NSString *gender = [resultSet stringForColumn:@"gender"]; int age = [resultSet intForColumn:@"age"]; NSLog(@"Name:%@,Gender:%@,Age:%d",name,gender,age); } [database close];
4.更新
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docPath = [paths objectAtIndex:0]; NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"]; FMDatabase *database = [FMDatabase databaseWithPath:dbPath]; if (![database open]) { return; } //参数必须是NSObject的子类,int,double,bool这种基本类型,需要封装成对应的包装类才可以 BOOL update = [database executeUpdate:@"update user set name = ? where age = ?",@"RyanTang", [NSNumber numberWithInt:24]]; if(update){ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"更新成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } [database close];
5.删除
NSString *dbPath = [self getDBPath]; FMDatabase *database = [FMDatabase databaseWithPath:dbPath]; if (![database open]) { return; } BOOL delete = [database executeUpdate:@"delete from user where name = ?",@"Tang"]; if (delete) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"删除成功" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } [database close];
6涉及多线程
FMDatabaseQueue * queue = [FMDatabaseQueue databaseQueueWithPath:database_path]; dispatch_queue_t q1 = dispatch_queue_create("queue1", NULL); dispatch_queue_t q2 = dispatch_queue_create("queue2", NULL); dispatch_async(q1, ^{ for (int i = 0; i < 50; ++i) { [queue inDatabase:^(FMDatabase *db2) { NSString *insertSql1= [NSString stringWithFormat: @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES (?, ?, ?)", TABLENAME, NAME, AGE, ADDRESS]; NSString * name = [NSString stringWithFormat:@"jack %d", i]; NSString * age = [NSString stringWithFormat:@"%d", 10+i]; BOOL res = [db2 executeUpdate:insertSql1, name, age,@"济南"]; if (!res) { NSLog(@"error to inster data: %@", name); } else { NSLog(@"succ to inster data: %@", name); } }]; } }); dispatch_async(q2, ^{ for (int i = 0; i < 50; ++i) { [queue inDatabase:^(FMDatabase *db2) { NSString *insertSql2= [NSString stringWithFormat: @"INSERT INTO '%@' ('%@', '%@', '%@') VALUES (?, ?, ?)", TABLENAME, NAME, AGE, ADDRESS]; NSString * name = [NSString stringWithFormat:@"lilei %d", i]; NSString * age = [NSString stringWithFormat:@"%d", 10+i]; BOOL res = [db2 executeUpdate:insertSql2, name, age,@"北京"]; if (!res) { NSLog(@"error to inster data: %@", name); } else { NSLog(@"succ to inster data: %@", name); } }]; } });
附:Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
参考http://www.cnblogs.com/peida/archive/2008/11/29/1343832.html
在用sqlite设计表时,突然想到一个问题,就是我设计的表中,每个表都有一个自己的整形 id值作为主键,其实可以不指定这么一个id值,sqlite内部本来就会为每个表加上一个 rowid,这个rowid可以当成一个隐含的字段使用,但 是由sqlite引擎来维护的,在3.0以前rowid是32位的整数,3.0以后是64位的整数,为什么不直接使用这个内部的rowid作为每个表的 id主键呢。
想到就立即先查找一下sqlite的文档,看看用指定INTEGER PRIMARY KEY AUTOINCREMENT 和不指定自增长字段用rowid有什么区别。相关的文档在这里:http://www.sqlite.org/autoinc.htmlhttp://www.sqlite.org/faq.html
使用自增长字段为主键有不少问题,比如维护或是在大型分布应用中主键冲突的解决等。在一些大型分布应用中主键一般选用guid,这可以有效的避免主键冲突,减少对主键维护的工程。当然,对于中小型的应用,自增长字段的好处更多一些,简单、快速。
Sqlite中,一个自增长字段定义为INTEGER PRIMARY KEY AUTOINCREMENT ,那么在插入一个新数据时,只需要将这个字段的值指定为NULL,即可由引擎自动设定其值,引擎会设定为最大的rowid+1。当然,也可以设置为非 NULL的数字来自己指定这个值,但这样就必须自己小心,不要引起冲突。当这个rowid的值大于所能表达的最大值 9223372036854775807 (3.0及以后版本的rowid最大值)后,rowid的新值会这个最大数之前随机找一个没被使用了的值。所以在rowid达到最大值前,rowid的值 是严格单调增加的。
INTEGER PRIMARY KEY AUTOINCREMENT 自增长字段的算法与rowid稍微有些不同。
第一,在达到最大值后,rowid会找已被删除的字段对应的rowid作为新值,而自增长字段则会丢出一个SQLITE_FULL的错误。
第二,自增长字段在增加新值时,是找一个从没被使用过的rowid作为新值,而rowid则是找最大已存在的rowid+1。这里对应用的影响会比较大,尤其是一些对id值有依赖的元记录,只适合使用自增长字段而不能用rowid。比如,我们设计一个元记录表:
Create table meta_struct(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar, type Integer);
然后,定义一个一级表,来描述其它表的结构:
Create table meta_table(tableid INTEGER, table_field integer)
最后,我们的应用可以根据这个一级表来产生实际使用的二级表。 这样为保证兼容性 meta_struct中的id必须是唯一的,如果有字段被删除,也不能重复使用这个字段的id值,不然,在数据库合并时,一级表和二级表就会混乱。所以 meta_struct表中的主键只能使用自增长字段,而不能用rowid。
第三,使用自增 长字段,引擎会自动产生一个sqlite_sequence表,用于记录每个表的自增长字段的已使用的最大值,用户可以看到,并可以用使用Update、 Delete和Insert操作,但不建议这么使用,这会让引擎混乱。如果使用rowid,也会有这么一个内部表,用户可以维护rowid值,但看不到。
这么看来,如果直接使用rowid来代替自增加字段,根据两者的细微的差别,需要注意是否与自己的应用冲突,如果没有冲突,那么用rowid会更快一点。
0 0
- 数据持久化之FMDB简单使用
- 数据持久化之FMDB--基本使用
- 数据持久化存储:FMDB的使用
- IOS数据持久化存储之SQLite3第三方库FMDB的使用
- 数据持久化(三)使用第三方类库FMDB
- 数据持久化(三)使用第三方类库FMDB
- 使用第三方类库FMDB实现数据持久化
- 数据持久化-CoreData、SQLite、FMDB
- FMDB&EGODatabase(数据持久化)
- 数据持久化-CoreData、SQLite、FMDB
- ios开发学习笔记--数据持久化之数据库(SQLite.swift)和FMDB
- 持久化FMDB
- iOS数据持久化——FMDB应用
- 数据持久化 coredata、sqlite、fmdb和sqlitepersistentobject
- FMDB——本地数据持久化浅谈
- ios数据本地持久化 之 使用文件持久化
- 数据持久化之sharedpreference的使用
- 数据持久化之plist使用
- [问题] Oracle 11g在安装时找不到文件em.ear
- inputStream to String
- 全志平台boot框架中增加设备驱动过程分析
- Ubuntu下搭建Web服务器
- hdu 3369 Robot
- 数据持久化之FMDB简单使用
- 使用python实现标记图像感兴区域
- oracle只装客户端远程连接数据库
- Unity 阴影
- 虚拟键盘代码
- 基于visual Studio2013解决面试题之0401非递归遍历二叉树
- loadrunner-27796错误寻求解决办法
- 复习————简单函数输出最大值
- eclipse中部署编写extjs代码时候的检测插件spket