【iOS】数据库SQLite3的使用

前面有两篇《【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>

【iOS】数据库SQLite3的使用_第1张图片

打开和关闭数据库

使用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);
    }];
}
打开数据库文件就可以看见刚才写入的数据了。
代码下载---请点击我。

你可能感兴趣的:(数据库,sqlite3)