数据持久化之数据库
数据库是数据持久化最重要的方式,也是开发中最常用的方式。
数据库的最大特点就是增、删、改、查,便于复杂数据的统一管理以及灵活使用。
需要导入库sqlite3.dylib。
数据库的本质是一个文件,存储于硬盘之上。
数据库流程:
1.引入库sqlite3.0.dylib
2.使用sqlite3.0dylib类对数据库进行操作
3.使用sqlite3_stmt类以及SQL语句进行数据的操作
优点:解决了归档查找数据困难的问题
缺点:需要对SQL语句比较了解
1.数据库的打开或者关闭
sqlite3_open()打开数据库的函数,返回值为整型,指打开操作的结果,若结果等于SQLITE_OK这个常量,则说明成功打开数据库。若打开失败则会返回相应的错误信息。
int sqlite3_open(const char*, sqlite3**);
int sqlite3_close(sqlite3*);
sqlite3_open() 的第一个参数为数据库文件名,第二个参数的类型sqlite3为一个结构体,它用于保存建立的数据库连接。当执行成功时,这两个均返回 SQLITE_OK, 失败则返回错误代码,可调用sqlite3_errmsg()或者sqlite3_errmsg16()给出错误描述。
2.预编译
sqlite3_prepare()要执行sql语句,必须先把它编译成字节码。
int sqlite3_prepare_v2(
sqlite3 *db,
const char *zSql,
int nByte,
sqlite3_stmt **ppStmt,
const char **pzTail
);此函数需要一个数据库连接的指针,将给定的SQL文本转换为预声明语句对象并返回一个指向它的指针,这个函数并不执行SQL语句。SQL语句中可以带有“?”,它代表不确定的值,当需要对这些“?”赋值时,可以使用sqlite3_bind_*()函数族:
1.int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
3.执行sql语句
这 一例程的功能是执行sqlite3_prepare()例程处理过的SQL语句,当返回的结果的第一行可以被获取时,这一例程将会返回,若要获得下一行的 结果,可再此调用这一例程,若执行的是无返回结果的SQL语句(例如INSERT),该例程将在一此调用中完成并返回。
当SQL语句执行成功时,此例程将返回SQLITE_DONE,当SQL语句执行成功且SQL返回一个单行结果集,此例程返回SQLITE_ROW,否则将返回错误代码,比如,如果不能打开数据库文件则会返回SQLITE_BUSY。
当返回值为SQLITE_ROW时,如需要对返回结果进行处理时,可以使用sqlite3_column_*()函数族:
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
其中参数 iCol为列的序号,从0开始。
4.sqlite3_column()
对 于SELECT语句,在使用上去sqlite3_step运行之后,需要将结果读出来。其实sqlit3_column()是一系列函数的总称,他们共同 的作用是从当前的结果按列号取出值。比如一个SELCET语句运行完之后,其中一条结果为1“张三”“男”。这个结果就包含三列,那么就可以利用该函数, 找到某一特定列的值,根据值类型的不同,需要调用不同的函数,比如针对第一列,类型为整数,就调用sqlite3_column_int(stmt,0) 来返回第一列的值;而在第二列的数据类型是文本text,调用sqlit3_column_text(stmt,0)得到第二列的文本信息。
还有其他版本:
*sqlite3_column_blob()
*sqlite3_column_bytes()
*sqlite3_column_bytes16()
*sqlite3_column_count()
*sqlite3_column_double()
*sqlite3_column_int()
*sqlite3_column_int64()
*sqlite3_column_text()
*sqlite3_column_text16()
*sqlite3_column_type()
*sqlite3_column_value()
5.销毁预编译的SQL语句
int sqlite3_finalize(sqlite3_stmt *pStmt);
sqlite3_finalize 和sqlite3_prepare 是相对的,当使用sqlite3_prepare 编译的SQL在使用完后,应该使用sqlite3_finalize 语句来释放掉它。
如果要多次使用处理过的SQL语句,且要更换里面绑定的参数,可以使用
int sqlite3_reset(sqlite3_stmt *pStmt);
来清除处理过的SQL语句里面绑定的所有参数,然后调用sqlite3_bind_*()函数族重新绑定参数即可。
6.sqlite3_exec()
为执行sql语句提供一种便捷的方法,只需要将sql语句的字符串(char *)传递给该函数即可,我们指定回调函数来处理执行后的返回值。不过,一般情况下,sqlie3_exec()函数多用于运行任何不返回数据的命令。它用于执行更新、插入、删除操作。
其他常用的还有:
sqlit3_column_count()统计列数
sqlit3_data_count()返回当前记录的列数
sqlit3_get_table()获取被查询的表的内容
sqlite3_srrmsg()返回错误信息
sqlite3_free()释放动态构造的sqlite语句
sqlite3_reset()重载sqlite语句
不太常用的API
sqlite3_column_database_name()获取数据库名
sqlite3_column_table_name()获取表名
sqlite3_origin_name()获取源名(索引名)
sqlite3_table_column_metadata()获取一列的详细信息(表名,建表类型)
//添加一个对象
+ (BOOL)addName:(NSString *)name phone:(NSString *)phone age:(int)age
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
BOOL success = NO;//默认添加失败
int result = sqlite3_prepare_v2(db, "insert into classA(name,phone,age) values(?,?,?)", -1, &stmt, nil);//准备SQL语句
if(SQLITE_OK == result)//语句无误
{
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);
sqlite3_bind_text(stmt, 2, [phone UTF8String], -1, nil);
sqlite3_bind_int(stmt, 3, age);
if(SQLITE_DONE == sqlite3_step(stmt))
{
success = YES;//添加成功
}
}
sqlite3_finalize(stmt);
return success;
}
//根据ID删除对象
+ (BOOL)deleteByID:(int)ID
{
sqlite3 *db = [DataBase openDB];
sqlite3_stmt *stmt= nil;
BOOL success = NO;//默认删除失败
int result = sqlite3_prepare_v2(db, "delete from classA where ID = ?", -1, &stmt, nil);
if(SQLITE_OK == result)
{
sqlite3_bind_int(stmt, 1, ID);
if(SQLITE_DONE == sqlite3_step(stmt))
{
success = YES;
}
}
sqlite3_finalize(stmt);
return success;
}
//更新
+ (BOOL)updateName:(NSString *)name phone:(NSString *)phone age:(int)age whereIDEqual:(int)ID
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
BOOL success = NO;//默认更新失败
int result = sqlite3_prepare_v2(db, "update classA set name = ?,phone = ?,age = ? where ID = ?", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);//1表示第一个?
sqlite3_bind_text(stmt, 2, [phone UTF8String], -1, nil);//2表示第二个?
sqlite3_bind_int(stmt, 3, age);
sqlite3_bind_int(stmt, 4, ID);
if(sqlite3_step(stmt) == SQLITE_DONE)
{
success = YES;//更新成功
}
}
sqlite3_finalize(stmt);
return success;
}
//信息条数
+ (int)count
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare_v2(db, "select count(*) from classA", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
if(SQLITE_ROW == sqlite3_step(stmt))
{
int count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return count;
}
}
sqlite3_finalize(stmt);
return 0;
}
//根据ID找对象
+ (Person *)findByID:(int)ID
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare_v2(db, "select * from classA where ID = ?", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
sqlite3_bind_int(stmt, 1, ID);//替换"?",1表示第一个?
if(SQLITE_ROW == sqlite3_step(stmt))//单步执行
{
const unsigned char *name = sqlite3_column_text(stmt, 1);
const unsigned char *phone = sqlite3_column_text(stmt, 2);
int age = sqlite3_column_int(stmt, 3);
Person *p = [[Person alloc] initWithID:ID name:[NSString stringWithUTF8String:(char *)name] phone:[NSString stringWithUTF8String:(char *)phone] age:age];
sqlite3_finalize(stmt);//释放stmt对象
return [p autorelease];
}
}
sqlite3_finalize(stmt);
return nil;
}
//找到所有对象
+ (NSMutableArray *)findAll
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;//陈述,是一个可以执行SQL语句的对象
int result = sqlite3_prepare_v2(db, "select * from classA", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)
{
NSMutableArray *allObject = [[NSMutableArray alloc] init];
while (SQLITE_ROW == sqlite3_step(stmt))//单步执行SQL语句
{
int ID = sqlite3_column_int(stmt, 0);//select结果集的第一列(第一个字段)
const unsigned char *name = sqlite3_column_text(stmt, 1);//select结果集的第二列(第二个字段)
const unsigned char *phone = sqlite3_column_text(stmt, 2);//select结果集的第三列(第三个字段)
int age = sqlite3_column_int(stmt, 3);
Person *p = [[Person alloc] initWithID:ID name:[NSString stringWithUTF8String:(char *)name] phone:[NSString stringWithUTF8String:(char *)phone] age:age];
[allObject addObject:p];
[p release];
}
sqlite3_finalize(stmt);//释放stmt对象
return [allObject autorelease];
}
sqlite3_finalize(stmt);
return nil;
}
以下是打开和关闭
static sqlite3 *dbPoint = nil;
+ (sqlite3 *)openDB
{
if(dbPoint)
{
return dbPoint;
}
//目标路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *sqlFilePath = [docPath stringByAppendingPathComponent:@"StudentDB.sqlite"];
//原始路径
NSString *orignFilePath = [[NSBundle mainBundle] pathForResource:@"StudentDB" ofType:@"sqlite"];
NSLog(@"%@\n%@",sqlFilePath,orignFilePath);
NSFileManager *fm = [NSFileManager defaultManager];
if([fm fileExistsAtPath:sqlFilePath] == NO)//如果doc下没有数据库,从bundle里面拷贝过来
{
NSError *err = nil;
if([fm copyItemAtPath:orignFilePath toPath:sqlFilePath error:&err] == NO)//如果拷贝失败
{
NSLog(@"open database error %@",[err localizedDescription]);
return nil;
}
}
NSLog(@"open DB at path:%@",sqlFilePath);
sqlite3_open([sqlFilePath UTF8String], &dbPoint);
return dbPoint;
}
+ (void)closeDB
{
if(dbPoint)
{
sqlite3_close(dbPoint);
}
}
数据库的最大特点就是增、删、改、查,便于复杂数据的统一管理以及灵活使用。
需要导入库sqlite3.dylib。
数据库的本质是一个文件,存储于硬盘之上。
数据库流程:
1.引入库sqlite3.0.dylib
2.使用sqlite3.0dylib类对数据库进行操作
3.使用sqlite3_stmt类以及SQL语句进行数据的操作
优点:解决了归档查找数据困难的问题
缺点:需要对SQL语句比较了解
1.数据库的打开或者关闭
sqlite3_open()打开数据库的函数,返回值为整型,指打开操作的结果,若结果等于SQLITE_OK这个常量,则说明成功打开数据库。若打开失败则会返回相应的错误信息。
int sqlite3_open(const char*, sqlite3**);
int sqlite3_close(sqlite3*);
sqlite3_open() 的第一个参数为数据库文件名,第二个参数的类型sqlite3为一个结构体,它用于保存建立的数据库连接。当执行成功时,这两个均返回 SQLITE_OK, 失败则返回错误代码,可调用sqlite3_errmsg()或者sqlite3_errmsg16()给出错误描述。
2.预编译
sqlite3_prepare()要执行sql语句,必须先把它编译成字节码。
int sqlite3_prepare_v2(
sqlite3 *db,
const char *zSql,
int nByte,
sqlite3_stmt **ppStmt,
const char **pzTail
);此函数需要一个数据库连接的指针,将给定的SQL文本转换为预声明语句对象并返回一个指向它的指针,这个函数并不执行SQL语句。SQL语句中可以带有“?”,它代表不确定的值,当需要对这些“?”赋值时,可以使用sqlite3_bind_*()函数族:
1.int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
3.执行sql语句
这 一例程的功能是执行sqlite3_prepare()例程处理过的SQL语句,当返回的结果的第一行可以被获取时,这一例程将会返回,若要获得下一行的 结果,可再此调用这一例程,若执行的是无返回结果的SQL语句(例如INSERT),该例程将在一此调用中完成并返回。
当SQL语句执行成功时,此例程将返回SQLITE_DONE,当SQL语句执行成功且SQL返回一个单行结果集,此例程返回SQLITE_ROW,否则将返回错误代码,比如,如果不能打开数据库文件则会返回SQLITE_BUSY。
当返回值为SQLITE_ROW时,如需要对返回结果进行处理时,可以使用sqlite3_column_*()函数族:
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
其中参数 iCol为列的序号,从0开始。
4.sqlite3_column()
对 于SELECT语句,在使用上去sqlite3_step运行之后,需要将结果读出来。其实sqlit3_column()是一系列函数的总称,他们共同 的作用是从当前的结果按列号取出值。比如一个SELCET语句运行完之后,其中一条结果为1“张三”“男”。这个结果就包含三列,那么就可以利用该函数, 找到某一特定列的值,根据值类型的不同,需要调用不同的函数,比如针对第一列,类型为整数,就调用sqlite3_column_int(stmt,0) 来返回第一列的值;而在第二列的数据类型是文本text,调用sqlit3_column_text(stmt,0)得到第二列的文本信息。
还有其他版本:
*sqlite3_column_blob()
*sqlite3_column_bytes()
*sqlite3_column_bytes16()
*sqlite3_column_count()
*sqlite3_column_double()
*sqlite3_column_int()
*sqlite3_column_int64()
*sqlite3_column_text()
*sqlite3_column_text16()
*sqlite3_column_type()
*sqlite3_column_value()
5.销毁预编译的SQL语句
int sqlite3_finalize(sqlite3_stmt *pStmt);
sqlite3_finalize 和sqlite3_prepare 是相对的,当使用sqlite3_prepare 编译的SQL在使用完后,应该使用sqlite3_finalize 语句来释放掉它。
如果要多次使用处理过的SQL语句,且要更换里面绑定的参数,可以使用
int sqlite3_reset(sqlite3_stmt *pStmt);
来清除处理过的SQL语句里面绑定的所有参数,然后调用sqlite3_bind_*()函数族重新绑定参数即可。
6.sqlite3_exec()
为执行sql语句提供一种便捷的方法,只需要将sql语句的字符串(char *)传递给该函数即可,我们指定回调函数来处理执行后的返回值。不过,一般情况下,sqlie3_exec()函数多用于运行任何不返回数据的命令。它用于执行更新、插入、删除操作。
其他常用的还有:
sqlit3_column_count()统计列数
sqlit3_data_count()返回当前记录的列数
sqlit3_get_table()获取被查询的表的内容
sqlite3_srrmsg()返回错误信息
sqlite3_free()释放动态构造的sqlite语句
sqlite3_reset()重载sqlite语句
不太常用的API
sqlite3_column_database_name()获取数据库名
sqlite3_column_table_name()获取表名
sqlite3_origin_name()获取源名(索引名)
sqlite3_table_column_metadata()获取一列的详细信息(表名,建表类型)
//添加一个对象
+ (BOOL)addName:(NSString *)name phone:(NSString *)phone age:(int)age
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
BOOL success = NO;//默认添加失败
int result = sqlite3_prepare_v2(db, "insert into classA(name,phone,age) values(?,?,?)", -1, &stmt, nil);//准备SQL语句
if(SQLITE_OK == result)//语句无误
{
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);
sqlite3_bind_text(stmt, 2, [phone UTF8String], -1, nil);
sqlite3_bind_int(stmt, 3, age);
if(SQLITE_DONE == sqlite3_step(stmt))
{
success = YES;//添加成功
}
}
sqlite3_finalize(stmt);
return success;
}
//根据ID删除对象
+ (BOOL)deleteByID:(int)ID
{
sqlite3 *db = [DataBase openDB];
sqlite3_stmt *stmt= nil;
BOOL success = NO;//默认删除失败
int result = sqlite3_prepare_v2(db, "delete from classA where ID = ?", -1, &stmt, nil);
if(SQLITE_OK == result)
{
sqlite3_bind_int(stmt, 1, ID);
if(SQLITE_DONE == sqlite3_step(stmt))
{
success = YES;
}
}
sqlite3_finalize(stmt);
return success;
}
//更新
+ (BOOL)updateName:(NSString *)name phone:(NSString *)phone age:(int)age whereIDEqual:(int)ID
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
BOOL success = NO;//默认更新失败
int result = sqlite3_prepare_v2(db, "update classA set name = ?,phone = ?,age = ? where ID = ?", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
sqlite3_bind_text(stmt, 1, [name UTF8String], -1, nil);//1表示第一个?
sqlite3_bind_text(stmt, 2, [phone UTF8String], -1, nil);//2表示第二个?
sqlite3_bind_int(stmt, 3, age);
sqlite3_bind_int(stmt, 4, ID);
if(sqlite3_step(stmt) == SQLITE_DONE)
{
success = YES;//更新成功
}
}
sqlite3_finalize(stmt);
return success;
}
//信息条数
+ (int)count
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare_v2(db, "select count(*) from classA", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
if(SQLITE_ROW == sqlite3_step(stmt))
{
int count = sqlite3_column_int(stmt, 0);
sqlite3_finalize(stmt);
return count;
}
}
sqlite3_finalize(stmt);
return 0;
}
//根据ID找对象
+ (Person *)findByID:(int)ID
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;
int result = sqlite3_prepare_v2(db, "select * from classA where ID = ?", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)//语句无误
{
sqlite3_bind_int(stmt, 1, ID);//替换"?",1表示第一个?
if(SQLITE_ROW == sqlite3_step(stmt))//单步执行
{
const unsigned char *name = sqlite3_column_text(stmt, 1);
const unsigned char *phone = sqlite3_column_text(stmt, 2);
int age = sqlite3_column_int(stmt, 3);
Person *p = [[Person alloc] initWithID:ID name:[NSString stringWithUTF8String:(char *)name] phone:[NSString stringWithUTF8String:(char *)phone] age:age];
sqlite3_finalize(stmt);//释放stmt对象
return [p autorelease];
}
}
sqlite3_finalize(stmt);
return nil;
}
//找到所有对象
+ (NSMutableArray *)findAll
{
sqlite3 *db = [DataBase openDB];//打开数据库
sqlite3_stmt *stmt = nil;//陈述,是一个可以执行SQL语句的对象
int result = sqlite3_prepare_v2(db, "select * from classA", -1, &stmt, nil);//准备SQL语句
if(result == SQLITE_OK)
{
NSMutableArray *allObject = [[NSMutableArray alloc] init];
while (SQLITE_ROW == sqlite3_step(stmt))//单步执行SQL语句
{
int ID = sqlite3_column_int(stmt, 0);//select结果集的第一列(第一个字段)
const unsigned char *name = sqlite3_column_text(stmt, 1);//select结果集的第二列(第二个字段)
const unsigned char *phone = sqlite3_column_text(stmt, 2);//select结果集的第三列(第三个字段)
int age = sqlite3_column_int(stmt, 3);
Person *p = [[Person alloc] initWithID:ID name:[NSString stringWithUTF8String:(char *)name] phone:[NSString stringWithUTF8String:(char *)phone] age:age];
[allObject addObject:p];
[p release];
}
sqlite3_finalize(stmt);//释放stmt对象
return [allObject autorelease];
}
sqlite3_finalize(stmt);
return nil;
}
以下是打开和关闭
static sqlite3 *dbPoint = nil;
+ (sqlite3 *)openDB
{
if(dbPoint)
{
return dbPoint;
}
//目标路径
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *sqlFilePath = [docPath stringByAppendingPathComponent:@"StudentDB.sqlite"];
//原始路径
NSString *orignFilePath = [[NSBundle mainBundle] pathForResource:@"StudentDB" ofType:@"sqlite"];
NSLog(@"%@\n%@",sqlFilePath,orignFilePath);
NSFileManager *fm = [NSFileManager defaultManager];
if([fm fileExistsAtPath:sqlFilePath] == NO)//如果doc下没有数据库,从bundle里面拷贝过来
{
NSError *err = nil;
if([fm copyItemAtPath:orignFilePath toPath:sqlFilePath error:&err] == NO)//如果拷贝失败
{
NSLog(@"open database error %@",[err localizedDescription]);
return nil;
}
}
NSLog(@"open DB at path:%@",sqlFilePath);
sqlite3_open([sqlFilePath UTF8String], &dbPoint);
return dbPoint;
}
+ (void)closeDB
{
if(dbPoint)
{
sqlite3_close(dbPoint);
}
}