@H_
502_0@新建一个Sigle View Application,命名为Persistence_
sqlite
@H_
502_0@为工程
添加sqlite3的库lib
sqlite3.dylib(点击工程->Build Phases->Link Binary With Libraries->
添加lib
sqlite3.dylib).
@H_
502_0@
修改ViewController.xib,
添加4个Label控件和4个TextField控件
@H_
502_0@
修改ViewController.h如下,并连接
输出口name、gender、age、education
@H_
502_0@#definekDataKey @"Data"
@H_
502_0@#definek
sqliteFileName @"data.db3"
@H_
502_0@@interfaceViewController : UIViewController
@H_
502_0@@property(nonatomic,retain)IBOutletUITextField *name;
@H_
502_0@@property(nonatomic,retain)IBOutletUITextField *gender;
@H_
502_0@@property(nonatomic,retain)IBOutletUITextField *age;
@H_
502_0@@property(nonatomic,retain)IBOutletUITextField *education;
@H_
502_0@-(NSString*)dataFilePath;
@H_
502_0@-(void)applicationWillResignActive:(NSNotification*)nofication;
@H_
502_0@@end
@H_
502_0@
修改ViewController.m如下
@H_
502_0@#import<
sqlite3.h>
@H_
502_0@@implementationViewController
@H_
502_0@@synthesizename,gender,age,education;
@H_
502_0@-(NSString*)dataFilePath{
@H_
502_0@ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
@H_
502_0@ NSString *documentsDirectory = [paths objectAtIndex:0];
@H_
502_0@ //return [documentsDirectory stringByAppendingPathComponent:kFileName];
@H_
502_0@ return [documentsDirectory stringByAppendingPathComponent:k
sqliteFileName];
@H_
502_0@}
@H_
502_0@-(void)didReceiveMemoryWarning
@H_
502_0@{
@H_
502_0@ [super didReceiveMemoryWarning];
@H_
502_0@ // Release any cached data,images,etc that aren't in use.
@H_
502_0@}
@H_
502_0@#pragma mark -View lifecycle
@H_
502_0@-(void)viewDidLoad
@H_
502_0@{
@H_
502_0@ // Do any additional setup after loading the view,typically from a nib.
@H_
502_0@ NSString *filePath = [self dataFilePath];
@H_
502_0@ NSLog(@"filePath=%@",filePath);
@H_
502_0@ if([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
@H_
502_0@
@H_
502_0@ //
sqlite3
@H_
502_0@
sqlite3 *database;
@H_
502_0@ //打开
数据库
@H_
502_0@ if(
sqlite3_open([filePath UTF8String],&database)!=
sqlITE_OK){//备注1
@H_
502_0@ //
数据库打开失败,
关闭数据库
@H_
502_0@
sqlite3_close(database);
@H_
502_0@ NSAssert(0,@"打开
数据库失败");
@H_
502_0@ }
@H_
502_0@
@H_
502_0@ char* errorMsg;
@H_
502_0@ NSString *create
sql = @"CREATE TABLE IF NOT EXISTS PERSON(name TEXT PRIMARY KEY,gender TEXT,age TEXT,education TEXT);";
@H_
502_0@ //创建表
@H_
502_0@ if(
sqlite3_exec(database,[create
sql UTF8String],NULL,&errorMsg)!=
sqlITE_OK){//备注2
@H_
502_0@ //创建表失败,
关闭数据库
@H_
502_0@
sqlite3_close(database);
@H_
502_0@ NSAssert1(0,@"创建表失败:%s",errorMsg);
@H_
502_0@ }
@H_
502_0@
@H_
502_0@ //
查询表
@H_
502_0@ NSString *query
sql = @"SELECT name,education FROMPERSON ORDER BY name";
@H_
502_0@
@H_
502_0@ //执行
查询,遍历
查询结果
@H_
502_0@
sqlite3_stmt *statment;
@H_
502_0@ if(
sqlite3_prepare_v2(database,[query
sql UTF8String],-1,&statment,nil) ==
sqlITE_OK){//备注3
@H_
502_0@ //
查询成功,执行遍历操作
@H_
502_0@ while(
sqlite3_step(statment) ==
sqlITE_ROW){//备注4
@H_
502_0@ const char* pName =(char*)
sqlite3_column_text(statment,0);//备注5
@H_
502_0@ if(pName!=NULL){
@H_
502_0@ self.name.text =[[NSString alloc]initWithUTF8String:pName];
@H_
502_0@ }
@H_
502_0@
@H_
502_0@ char* pGender =(char*)
sqlite3_column_text(statment,1);
@H_
502_0@ if(pGender!=NULL){
@H_
502_0@ self.gender.text =[[NSString alloc]initWithUTF8String:pGender];
@H_
502_0@ }
@H_
502_0@
@H_
502_0@ char* pAge =(char*)
sqlite3_column_text(statment,2);
@H_
502_0@ if(pAge!=NULL){
@H_
502_0@ self.age.text =[[NSString alloc]initWithUTF8String:pAge];
@H_
502_0@ }
@H_
502_0@
@H_
502_0@ char* pEducation =(char*)
sqlite3_column_text(statment,3);
@H_
502_0@ if(pEducation!=NULL){
@H_
502_0@ self.education.text =[[NSString alloc]initWithUTF8String:pEducation];
@H_
502_0@ }
@H_
502_0@ }
@H_
502_0@
sqlite3_finalize(statment);//备注6
@H_
502_0@ }
@H_
502_0@ //
关闭数据库
@H_
502_0@
sqlite3_close(database);//备注7
@H_
502_0@ }
@H_
502_0@ UIApplication *app = [UIApplication sharedApplication];
@H_
502_0@ [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotificationobject:app];
@H_
502_0@ [super viewDidLoad];
@H_
502_0@}
@H_
502_0@-(void)applicationWillResignActive:(NSNotification*)nofication{
@H_
502_0@ //
sqlite3
@H_
502_0@
sqlite3 *database;
@H_
502_0@ //打开
数据库
@H_
502_0@ if(
sqlite3_open([[self dataFilePath] UTF8String],&database)!=
sqlITE_OK){
@H_
502_0@ //
数据库打开失败,
关闭数据库
@H_
502_0@
sqlite3_close(database);
@H_
502_0@ NSAssert(0,@"打开
数据库失败");
@H_
502_0@ }
@H_
502_0@ char* errorMsg;
@H_
502_0@ NSString *update
sql = @"INSERT OR REPLACE INTOPERSON(name,education) VALUES(?,?,?);";
@H_
502_0@ //执行插入或更新操作
@H_
502_0@
sqlite3_stmt *statment;
@H_
502_0@ if(
sqlite3_prepare_v2(database,[update
sql UTF8String],nil)==
sqlITE_OK){
@H_
502_0@ //绑定变量
@H_
502_0@
sqlite3_bind_text(statment,1,[self.name.text UTF8String],NULL);//备注8
@H_
502_0@
sqlite3_bind_text(statment,2,[self.gender.text UTF8String],NULL);
@H_
502_0@
sqlite3_bind_text(statment,3,[self.age.text UTF8String],4,[self.education.text UTF8String],NULL);
@H_
502_0@ }
@H_
502_0@ if(
sqlite3_step(statment)!=
sqlITE_DONE){
@H_
502_0@ NSAssert1(0,@"更新表失败:%s",errorMsg);
@H_
502_0@ }
@H_
502_0@
sqlite3_finalize(statment);
@H_
502_0@ //
关闭数据库
@H_
502_0@
sqlite3_close(database);
@H_
502_0@}
@H_
502_0@
代码解释:
@H_
502_0@
备注1:sqlite3_open():打开
数据库
@H_
502_0@在操作
数据库之前,首先要打开
数据库。
@H_
502_0@这个
函数打开一个
sqlite
数据库文件的连接并且返回一个
数据库连接对象。
@H_
502_0@第1个参数:数据
文件路径必须用C风格字符串(不能用NSString),[filePath UTF8String]将filePath转换为C风格字符串。
@H_
502_0@第2个参数:是返回的
数据库连接对象。
@H_
502_0@
备注2:sqlite3_exec():执行
sql语句
@H_
502_0@ 第1个参数:
数据库指针,是前面open
函数得到的指针
@H_
502_0@ 第2个参数:const char *
sql是一条
sql 语句,以\0结尾。
@H_
502_0@ 第3个参数:
sqlite3_callback 是回调,当这条语句执行之后,
sqlite3会
调用这个回调
函数。
@H_
502_0@ 第4个参数:void*是一个指针,可以传递任何一个指针参数到这里,这个参数最终会传到回调
函数里面,如果不需要传递指针给回调
函数,可以填NULL
@H_
502_0@
备注3:sqlite3_prepare_v2():将
sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针
@H_
502_0@ 第1个参数:
数据库指针,是前面open
函数得到的指针
@H_
502_0@ 第2个参数:
sql语句,必须是C风格字符串
@H_
502_0@ 第3个参数:如果该参数小于0,则
函数取出z
sql中从开始到第一个0终止符的
内容;如果nByte不是负的,那么它就是这个
函数能从z
sql中读取的字节数的最大值。如果nBytes非负,z
sql在第一次遇见’/000/或’u000’的时候终止
@H_
502_0@ 第4个参数:上面提到z
sql在遇见终止符或者是达到设定的nByte之后结束,假如z
sql还有剩余的
内容,那么这些剩余的
内容被存放到pZTail中,不
包括终止符
@H_
502_0@
备注4:sqlite3_step()
@H_
502_0@ 这个过程用于执行有前面
sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次
调用sqlite3_setp()。继续
调用sqlite3_setp()直到这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),
sqlite3_step()只执行一次就返回
@H_
502_0@
备注5:sqlite3_column_text()
@H_
502_0@ 从结果集中
获取各列的值,需要注意的是:第一列的索引是0。
@H_
502_0@
备注6:sqlite3_finalize()
@H_
502_0@这个过程销毁前面被
sqlite3_prepare创建的准备语句,每个准备语句都必须使用这个
函数去销毁以防止内存泄露。
@H_
502_0@在空指针上
调用这个
函数没有什么影响,同时可以在准备语句的生命周期的任一时刻
调用这个
函数:在语句被执行前,一次或多次
调用
@H_
502_0@
sqlite_reset之后,或者在
sqlite3_step任何
调用之后。
@H_
502_0@
备注7:sqlite3_close()
@H_
502_0@
关闭前面使用
sqlite3_open打开的
数据库连接,任何与这个连接相关的准备语句必须在
调用这个
关闭函数之前被释放掉。
@H_
502_0@
备注8:sqlite3_bind_text()
@H_
502_0@第1个参数:指向在
sqlite3_prepare_v2()
调用中使用的
sqlite3_stme。
@H_
502_0@第2个参数:所绑定的变量的索引(
sql语句中第一个问号的索引),需要注意的是:第一个问号的索引是1,而不是0。
@H_
502_0@第3个参数:只有少数绑定
函数,比如用于绑定文本或二进制数据的绑定
函数,这个参数用来设定传递数据的长度。对于C字符串,可以传递-1来代替字符串的长度,意思是要是要使用整个字符串。
@H_
502_0@第4个参数:回调
函数,一般用于在语句执行后做内存清理相关的工作。可以设置为NULL。