首先,添加framework:libsqlite3.0.dylib
#import "/usr/include/sqlite3.h" |
并在Frameworks中加入所需的库,否则会报错:
加入库的方法是:
选择sqlite库:
//sqlite 常用语句
- [selfopenDataBase];
- [selfcreateTable];
- [selfinsertTable];
- [selfqueryTable];
- [selfdeleteTable];
- [selfqueryTable];
实现:
//opendatabase
- -(void)openDataBase
- {
- NSArray*documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
- NSString*databaseFilePath=[[documentsPathsobjectAtIndex:0]stringByAppendingPathComponent:@"db.sql"];
- if(sqlite3_open([databaseFilePathUTF8String],&database)==sqlITE_OK)
- {
- NSLog(@"opensqlitedbok.");
- }
- else
- {
- NSLog(@"cannotopensqlitedb");
- //closedatabase
- sqlite3_close(database);
- }
- }
//createtable
- -(void)createTable
- {
- char*errorMsg;
- constchar*createsql="createtableifnotexistspersons(idintegerprimarykeyautoincrement,nametext)";
- if(sqlite3_exec(database,createsql,NULL,&errorMsg)==sqlITE_OK)
- {
- NSLog(@"createok.");
- }
- else
- {
- NSLog(@"cannotcreatetable");
- [selfErrorReport:(NSString*)createsql];
- }
- }
//inserttable
- -(void)insertTable
- {
- char*errorMsg;
- constchar*insertsql="insertintopersons(name)values('田周辉')";
- if(sqlite3_exec(database,insertsql,&errorMsg)==sqlITE_OK)
- {
- NSLog(@"insertok.");
- }
- else
- {
- NSLog(@"cannotinsertittotable");
- [selfErrorReport:(NSString*)insertsql];
- }
- }
//error
- -(void)ErrorReport:(NSString*)item
- {
- char*errorMsg;
- if(sqlite3_exec(database,(constchar*)item,&errorMsg)==sqlITE_OK)
- {
- NSLog(@"%@ok.",item);
- }
- else
- {
- NSLog(@"error:%s",errorMsg);
- sqlite3_free(errorMsg);
- }
- }
//query
//delete
命令行:
sqlite3_open//打开数据库
- -(id)lookupSingularsql:(NSString*)sqlforType:(NSString*)rettype{
- @H_403_783@sqlite3_stmt*statement;
- @H_403_783@idresult;
- @H_403_783@if(statement=[selfprepare:sql]){
- @H_403_783@@H_403_783@if(sqlite3_step(statement)==sqlITE_ROW){
- @H_403_783@@H_403_783@if([rettypecompare:@"text"]==NSOrderedSame){
- @H_403_783@@H_403_783@chartemp_buf[256];
- @H_403_783@@H_403_783@memset(temp_buf,256);
- @H_403_783@@H_403_783@sprintf(temp_buf,"%s%s%s%s",(char*)sqlite3_column_text(statement,0),(char*)sqlite3_column_text(statement,1),
- @H_403_783@ @H_403_783@(char*)sqlite3_column_text(statement,2),3));
- @H_403_783@@H_403_783@result=[NSStringstringWithUTF8String:temp_buf];
- @H_403_783@@H_403_783@//result=[NSStringstringWithUTF8String:(char*)sqlite3_column_text(statement,0)];
- @H_403_783@@H_403_783@}elseif([rettypecompare:@"integer"]==NSOrderedSame){
- @H_403_783@@H_403_783@result=(id)sqlite3_column_int(statement,0);
- @H_403_783@@H_403_783@}
- @H_403_783@}
- @H_403_783@}
- @H_403_783@@H_403_783@sqlite3_finalize(statement);
- @H_403_783@@H_403_783@returnresult;
- @H_403_783@}
应该有个成员变量,比如我的代码:
- @interfaceDetailViewController:UIViewController{
- @H_403_783@UIPopoverController*popoverController;
- @H_403_783@UIToolbar*toolbar;
- @H_403_783@iddetailItem;
- @H_403_783@UILabel*detailDescriptionLabel;
- @H_403_783@sqlite3*database;
打开数据库
sqlite数据库是文件数据库,是保存在文件系统中的。因此需要知道文件保存到哪里,可参见iOS中对文件的操作。比如本文保存到Documents目录下。代码:
- NSArray*documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,YES);
- NSString*databaseFilePath=[[documentsPathsobjectAtIndex:0]stringByAppendingPathComponent:@"mydb"];
- if(sqlite3_open([databaseFilePathUTF8String],&database)==sqlITE_OK)
- {
- @H_403_783@@H_403_783@NSLog(@"opensqlitedbok.");
- }
通过ssh查看Documents目录,发现mydb文件已经创建。sqlite的策略是如果有该文件就打开,如果没有就创建文件,也就是创建数据库。
这里要注意,使用的是C语法,sqlite3_open传入的是database的地址。
- -(void)viewDidUnload{
- @H_403_783@@H_403_783@//Releaseanyretainedsubviewsofthemainview.
- @H_403_783@@H_403_783@//e.g.self.myOutlet=nil;
- @H_403_783@@H_403_783@sqlite3_close(database);
- @H_403_783@@H_403_783@self.popoverController=nil;
- }
建表语句
数据库打开以后,如果没有表,建表:
- char*errorMsg;
- constchar*createsql="createtableifnotexistspersons(idintegerprimarykeyautoincrement,nametext)";
- if(sqlite3_exec(database,&errorMsg)==sqlITE_OK){
- @H_403_783@@H_403_783@NSLog(@"createok.");
- }
这里要特别注意errorMsg传的是地址,因为该函数要通过地址引用来写报错字符信息。
向表中插入记录
和建表语句类似:
- constchar*insertsql="insertintopersons(name)values(‘张三’)";
- if(sqlite3_exec(database,&errorMsg)==sqlITE_OK){
- @H_403_783@@H_403_783@NSLog(@"insertok.");
- }
错误信息的处理
如果在多个地方使用errorMsg,那么每次使用完毕要清空一下字串,比如这样:
- if(sqlite3_exec(database,&errorMsg)==sqlITE_OK){
- @H_403_783@@H_403_783@NSLog(@"createok.");
- }else{
- @H_403_783@@H_403_783@NSLog(@"error:%s",errorMsg);
- @H_403_783@@H_403_783@sqlite3_free(errorMsg);
- }
查询结果集
结果集的查询,需要用到statement:
- constchar*selectsql="selectid,namefrompersons";
- sqlite3_stmt*statement;
- if(sqlite3_prepare_v2(database,nil)==sqlITE_OK){
- @H_403_783@@H_403_783@NSLog(@"selectok.");
- }
- while(sqlite3_step(statement)==sqlITE_ROW){
- @H_403_783@@H_403_783@int_id=sqlite3_column_int(statement,0);
- @H_403_783@@H_403_783@char*name=(char*)sqlite3_column_text(statement,1);
- @H_403_783@@H_403_783@NSLog(@"row>>id%i,name%s",name);
- }
- sqlite3_finalize(statement);
不过这里有个问题,看看打印的日志:
解决办法是,用nsstring替代char:
- while(sqlite3_step(statement)==sqlITE_ROW){
- @H_403_783@@H_403_783@int_id=sqlite3_column_int(statement,0);
- @H_403_783@@H_403_783@NSString*name=[[NSStringalloc]initWithCString:(char*)sqlite3_column_text(statement,1)encoding:NSUTF8StringEncoding];
- @H_403_783@@H_403_783@NSLog(@"row>>id%i,name%@",name);
- }
char生成nsstring的时候做一次显式的编码。问题解决:
写入数据库,用char的方式没有问题,写入数据库的编码是对的;
从库中取出,可能默认使用ascii解码,造成显示乱码。
使用sqlite c api,要经常参考官方函数文档:http://www.sqlite.org/c3ref/funclist.html