125Deaths重开之SQLite3的应用
时隔多日,终于重新收拾好心情再次写这个玩意了,话说这是什么玩意,别问我,鬼才知道呢。
在很久很久之前,为了熟悉ios的数据储存,在写这个的时候便想用SQLite或者Coredata来储存陷阱信息作为练习,中途遇到了如何简易将陷阱信息写入数据库的问题,后来又因为各种琐事就不了了之了,现今重开,继续学习研究。
初步想法是在MAC上手动创建SQLite数据库并编辑数据,然后移至沙盒中,这样app就可以直接抽取SQLite数据库中的数据,本想用Coredata实现,但在查资料中未能发现如何调用已存在的SQLite数据库(如果你在看这个文章并且知道的话,还请留言给我),感觉应该是可以的,只是我没有发现,留待以后查询资料,所以这里就先用SQLite语句进行实现了。
实现步骤基本如下:
- 创造SQLite3数据库,并创建Table、column写入数据
- 将SQLite数据库拽入Bundle
- 编写code将SQLite数据库从Bundle复制到沙盒的Document文件夹中
- 编写SQLite语句读取SQLite数据库的数据
- 将读取的数据复制给trapsModel变量
- 用trapsModel变量创建trap变量
主要记录一下将SQLite数据库从Bundle复制到沙盒的过程,以及读取SQLite数据库数据病赋值给trapsModel的过程。
将SQLite数据库从Bundle复制到沙盒:
//获取沙盒目标路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
//获取沙盒中SQLite数据库目的地路径
NSString *sqlFilePath = [docPath stringByAppendingPathComponent:@"TrapsModel.sqlite3"];
//获取Bundle中SQLite数据库的路径
NSString *orignFilePath = [[NSBundle mainBundle] pathForResource:@"TrapsModel" ofType:@"sqlite3"];
NSFileManager *fm = [NSFileManager defaultManager];
//如果doc下没有数据库,从bundle里面拷贝到沙盒中
if([fm fileExistsAtPath:sqlFilePath] == NO) {
NSLog(@"数据库不存在,准备拷贝");
NSError *err = nil;
//如果拷贝失败
if([fm copyItemAtPath:orignFilePath toPath:sqlFilePath error:&err] == NO) {
NSLog(@"拷贝失败,原因: %@",[err localizedDescription]);
}else
{
NSLog(@"拷贝成功");
}
}else
{
NSLog(@"数据库已存在");
}
读取SQLite数据库数据病赋值给trapsModel:
//获取沙盒目标路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
//获取沙盒中SQLite数据库目的地路径
NSString *sqlFilePath = [docPath stringByAppendingPathComponent:@"TrapsModel.sqlite3"];
//创建SQLite数据库指针
sqlite3 * db;
//打开数据库
sqlite3_open([sqlFilePath UTF8String], &db);
//定义错误字符串
char * errMsg;
//定义带参数查询的SQL语句,由于是用编号来获取数据,所以本不该用like关键字,以免获取多个数据,但由于现阶段只有两个数据,所以无碍
const char * selectSQL = "select * from trapsModel where id like ?";
sqlite3_stmt * stmt;
//预编译SQL语句,stmt变量保存了预编译结果的指针
int result = sqlite3_prepare_v2(database, selectSQL, -1, &stmt, nil);
//如果预编译成功
if(result == SQLITE_OK)
{
//为第一个?占位符绑定参数,其中num为一个随机数,用来确定指定编号的trap
sqlite3_bind_text(stmt, 1,[[NSString stringWithFormat:@"%%%ld%%",num]], -1, NULL);
//循环多次执行sqlite3_step()函数,病取出结果数据,同like关键字一样,因为数据少且不重复,故而选用此方法,这种循环多次执行在查询方便用的也比较多
while(sqlite3_step(stmt) == SQLITE_ROW)
{
//分别获取当前行不同列的数据
int cID = sqlite3_column_int(stmt, 0);
char * cName = (char *)sqlite3_column_text(stmt, 1);
char * cPic = (char *)sqlite3_cplumn_text(stmt, 2);
//将C字符转换成OC字符
NSString * name = [NSString stringWithUTF8String:cName];
NSString * pic = [NSString stringWithUTF8String:cPic];
//将数据封装到trapsModel类的变量(myTrapsModel)中,myTrapsModel在未可见的前文中已经声明
myTrapsModel = [trapsModel initWithId:cID name:name pic:pic];
//之后就可在后文中用myTrapsModel来创建trap类的变量了
}
//因为使用预编译Statement执行过SQL语句,所以调用sqlite3_finalize()函数关闭sqlite3_stmt
sqlite3_finalize(stmt);
}
//关闭数据库
sqlite3_close(db);