您的位置:首页 > 数据库

【iOS】数据库SQLite3的使用

2016-01-04 19:53 375 查看
前面有两篇《【iOS】数据库FMDB的使用》介绍了FMDB和一篇介绍了Core Data的使用《【iOS】数据库Core
Data的使用》。

这篇将要介绍SQLite3的使用。FMDB是SQLite3的一个封装,所以使用起来和两者的基本操作流程是一样的。

一、关于SQLite3

SQLite3在存储和检索大量数据方面非常有效。它能够对数据进行复杂的聚合,与使用对象执行这些操作相比,获得结的速度更快。SQLite3可以不需要将所有对象加载到内存中就可以获取这些信息。

SQLite3使用SQL(Structured Query Language,结构化查询语言)。SQL是与关系数据库交互的标准语言。SQLite3也是一种关系数据库。

二、SQLite3的使用

准备工作

#define FILE_NAME   @"SQLtest"
#define TABLE_NAME  @"SQLtest"

@interface ViewController (){
sqlite3 *dataBase;
}
@property (nonatomic,strong)NSArray *nameArray;
@end


添加依赖文件

新建一个项目;

添加依赖文件libsqlite3.dylib(Xcode7下面是libsqlite3.tbd);

项目在添加头文件#import<sqlite3.h>



打开和关闭数据库

使用SQLite3之前,必须先要打开数据库。这点和FMDB的操作是一致的。
数据库的打开和关闭操作:

sqlite3_open()
sqlite3_close()


/**
*  根据文件名获取文件路径
*
*  @param fileName 文件名
*
*  @return 返回文件路径
*/
- (NSString *)getFilePath:(NSString *)fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documetsDirectory = [paths objectAtIndex:0];
return [documetsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite",fileName]];
}
/**
*  打开数据库
*
*  @return YES:打开成功  NO:打开失败
*/
- (BOOL)openDataBase{
int result = sqlite3_open([self getFilePath:FILE_NAME].UTF8String, &dataBase);
if (result == SQLITE_OK) {
NSLog(@"数据库打开成功");
return YES;
}
else{
NSLog(@"数据库打开失败");
return NO;
}
}
/**
*  关闭数据库
*/
- (void)closeDataBase{
sqlite3_close(dataBase);
}


在打开数据库中的结果等于SQLITE_OK表示数据库打开成功,否则打开失败。SQLITE_OK是一个系统的宏定义。需要注意的是,在使用文件路径的时候,需要将OC字符串转为C字符串,好在OC给我们提供了这样的一个方法UTF8String。下面所涉及到的SQLite3的一些操作里面的OC字符串也都需要转为C字符串处理。

新建数据库创建表单

/**
*  数据库中创建表
*/
- (void)creatDataBase{
if (![self openDataBase]) {
return;
}
NSString *creatSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (rowid INTEGER PRIMARY KEY AUTOINCREMENT, name text,age text,address text)",TABLE_NAME];
char *errorMsg;
int result = sqlite3_exec(dataBase, creatSQL.UTF8String, NULL, NULL, &errorMsg);
if (result == SQLITE_OK) {
[self closeDataBase];
NSLog(@"表单:%@创建成功",TABLE_NAME);
}
else{
NSLog(@"表单:%@创建失败:%s",TABLE_NAME,errorMsg);
}
}


插入数据

这里的学生模型还是前面介绍FMDB里面的学生模型。

/**
*  以学生模型插入数据库
*
*  @param student 学生数据模型
*/
- (void)insterStudent:(Student *)student{
if (![self openDataBase]) {
return;
}
NSString *insterSQL = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (name,age,address) VALUES (?,?,?)",TABLE_NAME];
char *errorMsg;
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(dataBase, insterSQL.UTF8String, -1, &stmt, nil) == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, student.name.UTF8String, -1, nil);
sqlite3_bind_text(stmt, 2, student.age.UTF8String, -1, nil);
sqlite3_bind_text(stmt, 3, student.address.UTF8String, -1, nil);
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
NSLog(@"数据插入失败:%s",errorMsg);
}
else NSLog(@"数据插入成功");
sqlite3_finalize(stmt);
[self closeDataBase];
}
这里需要注意的是:

sqlite3_bind_text(stmt, <span style="color:#ff0000;"><strong>1</strong></span>, student.name.UTF8String, -1, nil);
sqlite3_bind_text(stmt, <span style="color:#ff0000;"><strong>2</strong></span>, student.age.UTF8String, -1, nil);
sqlite3_bind_text(stmt, <span style="color:#ff0000;"><strong>3</strong></span>, student.address.UTF8String, -1, nil);
这里的1 2 3 的顺序是根据创建表单时name、age和address的顺序来的。

sqlite3_bind_text是数据的类型。
下面是SQLite3里面支持的数据类型:

sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,void(*)(void*));
sqlite3_bind_double(sqlite3_stmt*, int, double);
sqlite3_bind_int(sqlite3_stmt*, int, int);
sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
sqlite3_bind_null(sqlite3_stmt*, int);
sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,void(*)(void*), unsigned char encoding);
sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);

sqlite3_prepare_v2(dataBase, insterSQL.UTF8String, -1, &stmt, nil
中的5各参数:

第一个参数:dataBase是一个sqlite3类型的数据;
第二个参数:是SQL语句;
第三个参数:-1表示传递的C字符串的长度,这样表示函数将使用整个字符串。对于其他情况,需要指定所传递数据的长度。

第四个参数:stmt是一个sqlite3_stmt类型的。

第五个参数:是可选调的函数回调,用于在语句执行后完成内存清理工作。通常这种函数使用malloc()释放以分配的内存。

更新数据

/**
*  更新一个学生的数据
*
*  @param student 学生数据模型
*/
- (void)updateStudent:(Student *)student{
if (![self openDataBase]) {
return;
}
NSString *updateSQL = [NSString stringWithFormat:@"UPDATE %@ SET age = '%@' WHERE name = '%@'",TABLE_NAME,student.age,student.name];
char *errorMsg;
if (sqlite3_exec(dataBase, updateSQL.UTF8String, NULL, NULL, &errorMsg) == SQLITE_OK) {
NSLog(@"数据更新成功");
[self closeDataBase];
}
else{
NSLog(@"数据修改失败:%s",errorMsg);
}
}


删除数据

/**
*  根据姓名删除学生
*
*  @param student 学生模型
*/
- (void)deleteStudent:(Student *)student{
if (![self openDataBase]) {
return;
}
NSString *deleteSQL = [NSString stringWithFormat:@"DELETE FROM %@ WHERE name = '%@'",TABLE_NAME,student.name];
char *errorMsg;
if (sqlite3_exec(dataBase, deleteSQL.UTF8String, NULL, NULL, &errorMsg) == SQLITE_OK) {
NSLog(@"数据删除成功");
[self closeDataBase];
}
else{
NSLog(@"数据删除失败:%s",errorMsg);
}
}
/**
*  删除全部数据
*/
- (void)deleteAllStudent{
if (![self openDataBase]) {
return;
}
NSString *deleteSQL = [NSString stringWithFormat:@"DELETE FROM %@ WHERE 1>0",TABLE_NAME];
char *errorMsg;
if (sqlite3_exec(dataBase, deleteSQL.UTF8String, NULL, NULL, &errorMsg) == SQLITE_OK) {
NSLog(@"数据删除成功");
[self closeDataBase];
}
else{
NSLog(@"数据删除失败:%s",errorMsg);
}
}


查询数据

/**
*  根据学生姓名查找学生
*
*  @param student 学生数据模型
*
*  @return 同一个姓名的学生
*/
- (NSMutableArray *)selectStudent:(Student *)student{
if (![self openDataBase]) {
return nil;
}
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSString *selecteSQL = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE name = '%@'",TABLE_NAME,student.name];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(dataBase, selecteSQL.UTF8String, -1, &stmt, nil) == SQLITE_OK) {
NSLog(@"筛选成功");
while (sqlite3_step(stmt) == SQLITE_ROW) {
NSMutableString *name=[NSMutableString stringWithCString:(char*)sqlite3_column_text(stmt, 1) encoding:NSUTF8StringEncoding];
NSMutableString *age=[NSMutableString stringWithCString:(char*)sqlite3_column_text(stmt, 2) encoding:NSUTF8StringEncoding];
NSString *address=[NSString stringWithCString:(char*)sqlite3_column_text(stmt, 3) encoding:NSUTF8StringEncoding];
Student *stu = [Student creatStudent:name age:age address:address];
[dataArray addObject:stu];
}
sqlite3_finalize(stmt);
[self closeDataBase];
return dataArray;
}
else{
NSLog(@"筛选失败");
return nil;
}
}
/**
*  获取数据库里面的全部数据
*
*  @return 学生数据的集合
*/
- (NSMutableArray *)selectAllStudent{
if (![self openDataBase]) {
return nil;
}
NSMutableArray *dataArray = [[NSMutableArray alloc] init];
NSString *selecteSQL = [NSString stringWithFormat:@"SELECT * FROM %@",TABLE_NAME];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(dataBase, selecteSQL.UTF8String, -1, &stmt, nil) == SQLITE_OK) {
NSLog(@"筛选成功");
while (sqlite3_step(stmt) == SQLITE_ROW) {
NSMutableString *name=[NSMutableString stringWithCString:(char*)sqlite3_column_text(stmt, 1) encoding:NSUTF8StringEncoding];
NSMutableString *age=[NSMutableString stringWithCString:(char*)sqlite3_column_text(stmt, 2) encoding:NSUTF8StringEncoding];
NSString *address=[NSString stringWithCString:(char*)sqlite3_column_text(stmt, 3) encoding:NSUTF8StringEncoding];
Student *stu = [Student creatStudent:name age:age address:address];
[dataArray addObject:stu];
}
sqlite3_finalize(stmt);
[self closeDataBase];
return dataArray;
}
else{
NSLog(@"筛选失败");
return nil;
}
}

三、触发增删改查操作

/**
*  随机生成一个学生数据模型
*
*  @return 学生数据模型
*/
- (Student *)getStudent{
Student *student = [Student creatStudent:self.nameArray[arc4random()%6] age:[NSString stringWithFormat:@"%u",arc4random()%100] address:[NSString stringWithFormat:@"%u",arc4random()%1000]];
return student;
}

/**
*  插入数据库按钮按下
*
*  @param sender sender description
*/
- (IBAction)insterBtnClick:(UIButton *)sender {
[self insterStudent:[self getStudent]];

}
/**
*  更新数据
*
*  @param sender sender description
*/
- (IBAction)modifyBtnClick:(UIButton *)sender {
[self updateStudent:[Student creatStudent:@"④" age:@"1" address:@"深圳"]];
}
/**
*  从数据库删除数据
*
*  @param sender sender description
*/
- (IBAction)deleteBtnClick:(UIButton *)sender {
[self deleteStudent:[Student creatStudent:@"②" age:nil address:nil]];
}
/**
*  清空数据库
*
*  @param sender sender description
*/
- (IBAction)clearAll:(UIButton *)sender {
[self deleteAllStudent];
}
/**
*  查找同一个姓名的学生
*
*  @param sender sender description
*/
- (IBAction)selectBtnClick:(UIButton *)sender {
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:[self selectStudent:[Student creatStudent:@"①" age:nil address:nil]]];
[arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Student *student = (Student *)obj;
NSLog(@"name = %@",student.name);
NSLog(@"age = %@",student.age);
NSLog(@"address = %@",student.address);
}];
}

/**
*  获取全部数据
*
*  @param sender sender description
*/
- (IBAction)selectAllBtnClick:(UIButton *)sender {
NSMutableArray *arr = [[NSMutableArray alloc] initWithArray:[self selectAllStudent]];
[arr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Student *student = (Student *)obj;
NSLog(@"name = %@",student.name);
NSLog(@"age = %@",student.age);
NSLog(@"address = %@",student.address);
}];
}
打开数据库文件就可以看见刚才写入的数据了。

代码下载---请点击我。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: