iPhone开发之数据库使用
转载自 http://blog.sina.com.cn/s/blog_615db9540100eidu.html
?
由于第一个iPhone程序就使用到了数据库,所以首先来说下iPhone数据库的使用。iPhone使用的是sqlite数据库,我用了firefox的插件SqliteManager来管理sqlite,这个插件很好用,可以很方便的进行视图化的创建以及管理sqlite。废话不多说,进入正题。
要使用sqlite首先要在Frameworks中引入libsqlite3.0.dylib这个文件,具体步骤我就略过了,然后创建数据库,建好后将数据库添加到Resources目录下(记得勾选Copyitems into ...这个选项),现在准备工作都已经做好,下面进入代码编写。
为了方便使用,以及以后的维护,我在这里创建了一个类将数据库的相关代码进行了封装。创建一个NSObject类,我在这里取名为GADatabase,然后在实现文件中添加以下代码:
#import<sqlite3.h>
idgetColValue(sqlite3_stmt *stmt,int iCol) {
???int type = sqlite3_column_type(stmt, iCol);
???switch (type) {
?????? caseSQLITE_INTEGER:
????????? return[NSNumber numberWithInt:sqlite3_column_int(stmt,iCol)];
?????????break;
?????? caseSQLITE_FLOAT:
????????? return[NSNumber numberWithDouble:sqlite3_column_double(stmt,iCol)];
?????????break;
?????? caseSQLITE_TEXT:
????????? return[NSString stringWithUTF8String:sqlite3_column_text(stmt,iCol)];
?????????break;
?????? caseSQLITE_BLOB:
????????? return[NSData dataWithBytes:sqlite3_column_blob(stmt, iCol)length:sqlite3_column_bytes(stmt, iCol)];
?????????break;
?????? caseSQLITE_NULL:
????????? return@"";
?????????break;
??????default:
????????? return@"NONE";
?????????break;
???}
}
在这里,我使用了C风格的定义,并且定义在了@implementation之外以方便使用,有了这个函数在以后的数据提取时很方便,其中的数据类型可根据实际情况进行增减。OK,现在在@implementation与@end之间添加下面的代码以获取iphone中sqlite的地址:
+ (NSString*)pathForDatabase {
???NSArray *arrayOfPaths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
???NSString *path = [arrayOfPaths objectAtIndex:0];
???path = [pathstringByAppendingPathComponent:@"yourDatabaseName.sqlite"];
???
???NSLog(path);
???
???NSFileManager *fileManager = [NSFileManagerdefaultManager];
???if(![fileManager fileExistsAtPath:path]){
?????? NSString*databaseSource = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:@"yourDatabaseName.sqlite"];
??????if(![fileManager copyItemAtPath:databaseSource toPath:patherror:nil]){
????????? returnnil;
??????}
???}
???return path;
}
好了,现在可以写sql语句了,我简单举几个例子:
查询某一个字段:
- (NSString*)select:(NSString *)Parameter {
???sqlite3 *database;
???sqlite3_stmt *stm;
???NSString *result = [NSString string];
???NSString *sql = [NSString stringWithFormat:@"SELECT columnName FROMtable WHERE columnName='%@'", Parameter];
???
???if(sqlite3_open([[GADatabase pathForDatabase] UTF8String],&database) == SQLITE_OK) {
??????if(sqlite3_prepare_v2(database, [sql UTF8String], -1,&stm, NULL) == SQLITE_OK) {
?????????if(sqlite3_step(stm) == SQLITE_ROW) {
???????????? result =getColValue(stm, 0);
?????????}
??????}
??????sqlite3_finalize(stm);
???}
???sqlite3_close(database);
???return result;
}
若查询多字段,可以用一个数组并结合一个自定义类来存储,例:
- (NSMutableArray*)selectUsers {
???sqlite3 *database;
???sqlite3_stmt *stm;
???NSMutableArray *result = [[NSMutableArray alloc]init];
???NSString *sql = @"SELECT * FROM users";
???
???if(sqlite3_open([[GADatabase pathForDatabase] UTF8String],&database) == SQLITE_OK) {
??????if(sqlite3_prepare_v2(database, [sql UTF8String], -1,&stm, NULL) == SQLITE_OK) {
?????????while(sqlite3_step(stm) == SQLITE_ROW) {
???????????? GAData*userObj = [[GAData alloc] init];
???????????? userObj.rId= getColValue(stm, 0);
????????????userObj.userName = getColValue(stm, 1);
????????????userObj.passWord = getColValue(stm, 2);
???????????? [resultaddObject:userObj];
???????????????[userObj release];
?????????}
??????}
??????sqlite3_finalize(stm);
???}
???sqlite3_close(database);
???returnresult;???
}
GAData的类定义如下:
#import<Foundation/Foundation.h>
@interface GAData :NSObject {
???NSNumber *rId;
???NSString *userName;
???NSString *passWord;
}
@property(nonatomic,retain)NSNumber *rId;
@property(nonatomic,retain)NSString *userName;
@property(nonatomic,retain)NSString *passWord;
@end
#import"GAData.h"
@implementationGAData
@synthesizerId;
@synthesizeuserName;
@synthesizepassWord;
@end
向数据库添加数据:
- (void)addUser:(GAData *)addUserObj {
???sqlite3 *database;
???NSString *sql = [NSString stringWithFormat:@"INSERT INTO users(userName, passWord) VALUES('%@','%@')",
????????????????addUserObj.userName,addUserObj.passWord];
???
???int status = sqlite3_open([[GADatabase pathForDatabase]UTF8String], &database);
???if(status != SQLITE_OK) {
??????return;
???}
???status = sqlite3_exec(database, [sql UTF8String], 0, 0,NULL);
???if(status != SQLITE_OK) {
??????return;
???}
???sqlite3_close(database);
}
删除,修改与添加类似,无非是sql语句的不同,就不再举例了,下面我再说下sqlite中的时间函数,由于目前为止我还只用到了关于计算天数的函数,所以其他的我就不介绍了,大家可以在网上搜索一下,看下面这条sql语句:
SELECT columnNameFROM table WHERE(julianday(date(columnName))-julianday(date('now')))>10
julianday()这个函数会返回一个天数,从格林威治时间公元前4714年11月24号开始算起。date()函数返回一个以“YYYY-MM-DD”为格式的日期。因此上面那条语句也就不难理解了。
关于数据库方面的我就暂时写这么多了,有不够好的地方或者错误的地方欢迎大家指出来,大家一起学习嘛。最后,我再提醒一句,如果修改了Resources目录下的数据库内容,需要将原先编译好的程序删除掉,重新编译,或者找到程序运行时的路径,删掉Documents文件夹下的数据库文件,再重新编译运行,只有这样,你程序中的数据库才会更新,切记!
?