iPhone开发【二十四】数据持久化总结之第4篇—sqlite3数据库
来源:互联网 发布:中文域名好吗 编辑:程序博客网 时间:2024/04/25 20:26
转载请注明出处,原文网址:http://blog.csdn.net/m_changgong/article/details/8284135 作者:张燕广
实现的功能:1)演示使用sqlite3持久化数据。
关键词:数据持久化 sqlite3 数据库
1、将上一篇iPhone开发【二十二】数据持久化总结之第3篇归档(NSKeyedArchiver、NSKeyedUnarchiver)的工程拷贝一份,名称修改为Persistence-sqlite,工程结构如下:
Person类已经没用了,可以删掉。
2、为工程添加sqlite3的库libsqlite3.dylib,如下图所示:
3、主要修改了ViewController类,ViewController.h如下:
- <span style="font-size:18px;">#define kFileName @"archive"
- #define kDataKey @"Data"
- #define kSqliteFileName @"data.db3"
- #import <UIKit/UIKit.h>
- @interface ViewController : UIViewController
- @property(nonatomic,retain)IBOutlet UITextField *name;
- @property(nonatomic,retain)IBOutlet UITextField *gender;
- @property(nonatomic,retain)IBOutlet UITextField *age;
- @property(nonatomic,retain)IBOutlet UITextField *education;
- -(NSString *)dataFilePath;
- -(void)applicationWillResignActive:(NSNotification *)nofication;
- @end</span>
- <span style="font-size:18px;">#import "ViewController.h"
- #import "Person.h"
- #import <sqlite3.h>
- @implementation ViewController
- @synthesize name,gender,age,education;
- -(NSString *)dataFilePath{
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- //return [documentsDirectory stringByAppendingPathComponent:kFileName];
- return [documentsDirectory stringByAppendingPathComponent:kSqliteFileName];
- }
- - (void)didReceiveMemoryWarning
- {
- [super didReceiveMemoryWarning];
- // Release any cached data, images, etc that aren't in use.
- }
- #pragma mark - View lifecycle
- - (void)viewDidLoad
- {
- // Do any additional setup after loading the view, typically from a nib.
- NSString *filePath = [self dataFilePath];
- NSLog(@"filePath=%@",filePath);
- if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
- //属性列表
- /*
- NSArray *array = [[NSArray alloc]initWithContentsOfFile:filePath];
- name.text = [array objectAtIndex:0];
- gender.text = [array objectAtIndex:1];
- age.text = [array objectAtIndex:2];
- education.text = [array objectAtIndex:3];
- [array release];*/
- //归档
- /*
- NSData *data = [[NSMutableData alloc]initWithContentsOfFile:[self dataFilePath]];
- NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
- Person *person = [unarchiver decodeObjectForKey:kDataKey];
- [unarchiver finishDecoding];
- name.text = person.name;
- gender.text = person.gender;
- age.text = person.age;
- education.text = person.education;
- [unarchiver release];
- [data release];*/
- //sqlite3
- sqlite3 *database;
- //打开数据库
- if(sqlite3_open([filePath UTF8String], &database)!=SQLITE_OK){//备注1
- //数据库打开失败,关闭数据库
- sqlite3_close(database);
- NSAssert(0,@"打开数据库失败");
- }
- char* errorMsg;
- NSString *createSQL = @"CREATE TABLE IF NOT EXISTS PERSON (name TEXT PRIMARY KEY,gender TEXT,age TEXT,education TEXT);";
- //创建表
- if(sqlite3_exec(database, [createSQL UTF8String], NULL, NULL, &errorMsg)!=SQLITE_OK){//备注2
- //创建表失败,关闭数据库
- sqlite3_close(database);
- NSAssert1(0, @"创建表失败:%s", errorMsg);
- }
- //查询表
- NSString *querySQL = @"SELECT name,gender,age,education FROM PERSON ORDER BY name";
- //执行查询,遍历查询结果
- sqlite3_stmt *statment;
- if(sqlite3_prepare_v2(database, [querySQL UTF8String], -1, &statment, nil) == SQLITE_OK){//备注3
- //查询成功,执行遍历操作
- while(sqlite3_step(statment) == SQLITE_ROW){//备注4
- const char* pName = (char*)sqlite3_column_text(statment, 0);//备注5
- if(pName!=NULL){
- self.name.text = [[NSString alloc]initWithUTF8String:pName];
- }
- char* pGender = (char*)sqlite3_column_text(statment, 1);
- if(pGender!=NULL){
- self.gender.text = [[NSString alloc]initWithUTF8String:pGender];
- }
- char* pAge = (char*)sqlite3_column_text(statment, 2);
- if(pAge!=NULL){
- self.age.text = [[NSString alloc]initWithUTF8String:pAge];
- }
- char* pEducation = (char*)sqlite3_column_text(statment, 3);
- if(pEducation!=NULL){
- self.education.text = [[NSString alloc]initWithUTF8String:pEducation];
- }
- }
- sqlite3_finalize(statment);//备注6
- }
- //关闭数据库
- sqlite3_close(database);//备注7
- }
- UIApplication *app = [UIApplication sharedApplication];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
- [super viewDidLoad];
- }
- -(void)applicationWillResignActive:(NSNotification *)nofication{
- //属性列表
- /*
- NSMutableArray *array = [[NSMutableArray alloc]init];
- [array addObject:name.text];
- [array addObject:gender.text];
- [array addObject:age.text];
- [array addObject:education.text];
- [array writeToFile:[self dataFilePath] atomically:YES];
- [array release];*/
- //归档
- /*
- Person *person = [[Person alloc]init];
- person.name = name.text;
- person.gender = gender.text;
- person.age = age.text;
- person.education = education.text;
- NSMutableData *data = [[NSMutableData alloc]init];
- NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
- [archiver encodeObject:person forKey:kDataKey];
- [archiver finishEncoding];
- [data writeToFile:[self dataFilePath] atomically:YES];
- [person release];
- [archiver release];
- [data release];*/
- //sqlite3
- sqlite3 *database;
- //打开数据库
- if(sqlite3_open([[self dataFilePath] UTF8String], &database)!=SQLITE_OK){
- //数据库打开失败,关闭数据库
- sqlite3_close(database);
- NSAssert(0,@"打开数据库失败");
- }
- char* errorMsg;
- NSString *updateSQL = @"INSERT OR REPLACE INTO PERSON(name,gender,age,education) VALUES(?,?,?,?);";
- //执行插入或更新操作
- sqlite3_stmt *statment;
- if(sqlite3_prepare_v2(database, [updateSQL UTF8String], -1, &statment, nil) == SQLITE_OK){
- //绑定变量
- sqlite3_bind_text(statment, 1, [self.name.text UTF8String], -1, NULL);//备注8
- sqlite3_bind_text(statment, 2, [self.gender.text UTF8String], -1, NULL);
- sqlite3_bind_text(statment, 3, [self.age.text UTF8String], -1, NULL);
- sqlite3_bind_text(statment, 4, [self.education.text UTF8String], -1, NULL);
- }
- if(sqlite3_step(statment)!=SQLITE_DONE){
- NSAssert1(0, @"更新表失败:%s", errorMsg);
- }
- sqlite3_finalize(statment);
- //关闭数据库
- sqlite3_close(database);
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- self.name = nil;
- self.gender = nil;
- self.age = nil;
- self.education = nil;
- }
- -(void)dealloc{
- [name release];
- [gender release];
- [age release];
- [education release];
- }
- - (void)viewWillAppear:(BOOL)animated
- {
- [super viewWillAppear:animated];
- }
- - (void)viewDidAppear:(BOOL)animated
- {
- [super viewDidAppear:animated];
- }
- - (void)viewWillDisappear:(BOOL)animated
- {
- [super viewWillDisappear:animated];
- }
- - (void)viewDidDisappear:(BOOL)animated
- {
- [super viewDidDisappear:animated];
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- // Return YES for supported orientations
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- @end</span>
备注1:sqlite3_open():打开数据库
在操作数据库之前,首先要打开数据库。
这个函数打开一个sqlite数据库文件的连接并且返回一个数据库连接对象。
第1个参数:数据文件路径必须用C风格字符串(不能用NSString),[filePath UTF8String]将filePath转换为C风格字符串。
第2个参数:是返回的数据库连接对象。
第1个参数:数据库指针,是前面open函数得到的指针
第2个参数:const char *sql是一条sql 语句,以\0结尾。
第3个参数:sqlite3_callback 是回调,当这条语句执行之后,sqlite3会调用这个回调函数。
第4个参数:void*是一个指针,可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL
备注3:sqlite3_prepare_v2():将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针
第1个参数:数据库指针,是前面open函数得到的指针
第2个参数:sql语句,必须是C风格字符串
第3个参数:如果该参数小于0,则函数取出zSql中从开始到第一个0终止符的内容;如果nByte不是负的,那么它就是这个函数能从zSql中读取的字节数的最大值。如果nBytes非负,zSql在第一次遇见’/000/或’u000’的时候终止
第4个参数:上面提到zSql在遇见终止符或者是达到设定的nByte之后结束,假如zSql还有剩余的内容,那么这些剩余的内容被存放到pZTail中,不包括终止符
备注4:sqlite3_step()
这个过程用于执行有前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()直到这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回
备注5:sqlite3_column_text()
从结果集中获取各列的值,需要注意的是:第一列的索引是0。
备注6:sqlite3_finalize()
这个过程销毁前面被sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个函数去销毁以防止内存泄露。
在空指针上调用这个函数没有什么影响,同时可以在准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或多次调用
sqlite_reset之后,或者在sqlite3_step任何调用之后。
备注7:sqlite3_close()
关闭前面使用sqlite3_open打开的数据库连接,任何与这个连接相关的准备语句必须在调用这个关闭函数之前被释放掉。
备注8:sqlite3_bind_text()
第1个参数:指向在sqlite3_prepare_v2()调用中使用的sqlite3_stme。
第2个参数:所绑定的变量的索引(sql语句中第一个问号的索引),需要注意的是:第一个问号的索引是1,而不是0。
第3个参数:只有少数绑定函数,比如用于绑定文本或二进制数据的绑定函数,这个参数用来设定传递数据的长度。对于C字符串,可以传递-1来代替字符串的长度,意思是要是要使用整个字符串。
第4个参数:回调函数,一般用于在语句执行后做内存清理相关的工作。可以设置为NULL。4、数据库文件的保存位置是: /Users/duobianxing/Library/Application Support/iPhone Simulator/5.0/Applications/CC47C118-7FE7-4718-A4AA-635FBCC36AED/Documents/data.db3
- iPhone开发【二十四】数据持久化总结之第4篇—sqlite3数据库
- iPhone开发【二十四】数据持久化总结之第4篇—sqlite3数据库
- iPhone开发【二十】数据持久化总结之第1篇—NSUserDefaults
- iPhone开发【二十六】数据持久化总结之第5篇—CoreData技术
- iPhone开发【二十】数据持久化总结之第1篇—NSUserDefaults
- iPhone开发【二十一】数据持久化总结之第2篇—属性文件(.plist)
- iPhone开发【二十二】数据持久化总结之第3篇—归档(NSKeyedArchiver、NSKeyedUnarchiver)
- iPhone开发【二十一】数据持久化总结之第2篇—属性文件(.plist)
- iPhone开发【二十二】数据持久化总结之第3篇—归档(NSKeyedArchiver、NSKeyedUnarchiver)
- iPhone开发【二十七】数据持久化总结之第6篇(终结篇)—5种数据持久化方法对比总结
- iPhone开发【二十七】数据持久化总结之第6篇(终结篇)—5种数据持久化方法对比总结
- iphone开发中数据持久化之——模型对象归档(二)
- iPhone数据持久化(plist|Archiver|Sqlite3)
- iPhone数据持久化(plist|Archiver|Sqlite3)
- iPhone数据持久化(plist|Archiver|Sqlite3)
- IOS开发--数据持久化篇之文件存储(二)
- iphone开发中数据持久化之——属性列表序列化(一)
- iphone开发中数据持久化之——嵌入式SQLite(三)
- oracle 12541错误解决办法
- BIT1055The Euler function
- 【Android开发学习06】Android中的文件I/O操作
- ZTE将在MWC大会上展示Firefox操作系统手机
- php 登录之后,返回会员上一次访问的路径网址
- iPhone开发【二十四】数据持久化总结之第4篇—sqlite3数据库
- errors running builder 'Android Pre Compiler' on project'项目名称'
- GDI坐标系统(下)
- Lucene 初试
- 《敏捷个人》周刊 第16期
- ALUA --- Asymmetric Logic Unit Access
- [C#.NET] 使用 Google Maps API 查某一個地址的經度和緯度
- Linux-ASoC驱动归纳总结:
- 推荐几款最为流行的Java IDE