iOS中的SQLite

2020-08-10  本文已影响0人  伶俐ll

一、SQLite3

首先要添加库文件libsqlite3.dylib和导入主头文件#import <sqlite3.h>

sqlite3_open()

根据文件路径打开数据库,如果不存在,则会创建一个新的数据库

    sqlite3 *db = NULL;
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"demo.sqlite"];
    /** 
     * filename: 数据库文件的存放路径
     * ppDb: 一个打开的数据库实例
     * sqlite3_open()会返回一个int类型的值, 这个值代表着打开数据库是否成功,如果result等于常量SQLITE_OK,则表示成功打开数据库
     */
    int result = sqlite3_open(path.UTF8String, &db);
    if (result == SQLITE_OK) {
        NSLog(@"--数据库打开成功--%@",path);
    }

sqlite3_exec()

sqlite3_exec()可以执行任何SQL语句,比如创表、更新、插入和删除操作。但是一般不用它执行查询语句,因为它不会返回查询到的数据

    //建表
    NSString *sql = @"create table if not exists t_student(id integer primary key autoincrement, name test, age integer);";
    //插入数据
    //NSString *sql = @"insert into t_student(name,age) values ('lisi',12)";
    char *error = nil;
    /** 
     * sqlite3*: 需要执行sql语句的数据库
     * const char *sql:需要执行的sql语句
     * int (*callback)(void*,int,char**,char**):执行完sql语句之后的回调方法
     * void *:回调方法的参数
     * char **errmsg :错误信息
     */
    int execResult = sqlite3_exec(db, [sql UTF8String], NULL, NULL, &error);
    if (execResult == SQLITE_OK) {
        NSLog(@"成功");
    }

带占位符插入数据

    //插入语句
    NSString *sql = @"insert into t_student(name,age) values (?,?)";
    NSArray *args = @[@"wanger",@(23)];
    sqlite3_stmt *stmt = nil;
    //sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
    int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
    if (result == SQLITE_OK) {
        NSLog(@"");
    }
    for (int i = 0; i<args.count; i++) {
        NSObject *objc = args[i];
        if ([objc isKindOfClass:[NSNumber class]]) {
            NSNumber *number = ( NSNumber *)objc;
            if (strcmp([number objCType], @encode(int))) {
                sqlite3_bind_int(stmt, i + 1, number.intValue);
            }else if(strcmp([(NSNumber *)objc objCType], @encode(float))) {
                sqlite3_bind_double(stmt, i + 1, number.doubleValue);
            }else if(strcmp([(NSNumber *)objc objCType], @encode(double))) {
                sqlite3_bind_double(stmt, i + 1, number.doubleValue);
            }
        }else if([objc isKindOfClass:[NSString class]]){
            NSString *str = (NSString *)objc;
            /**
             sqlite3_stmt*,
             int:占位符的位置,第一个占位符的位置是1,不是0
             const char*:占位符要绑定的值
             int:在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
             void(*)(void*):一个可选的函数回调,一般用于在语句执行后完成内存清理工作
             */
            sqlite3_bind_text(stmt, i + 1, [str UTF8String], -1, SQLITE_TRANSIENT);
        }
    }
    /**
     执行SQL语句,返回SQLITE_DONE代表成功执行完毕
     */
    sqlite3_step(stmt);
    /**
     重置sqlite3_stmt *对象,返回SQLITE_OK代表重置成功
     */
    sqlite3_reset(stmt);
    /**
     销毁sqlite3_stmt *对象,返回SQLITE_OK代表销毁成功
     */
    sqlite3_finalize(stmt);

查询数据

    //查询语句
    NSString *sql = @"select id, name, age from t_student;";
    sqlite3_stmt *stmt = nil;
    //sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
    int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
    if (result == SQLITE_OK) {
        NSLog(@"");
    }
    
    NSMutableArray *arrM = [NSMutableArray array];
    //sqlite3_step()返回SQLITE_ROW代表遍历到一条新记录
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        // 从stmt中取出提取到的数据
        //获得一条数据中字段的个数
        int count = sqlite3_column_count(stmt);
        NSMutableDictionary *record = [NSMutableDictionary dictionary];
        for (int i = 0; i < count; i++) {
            //取得key值
            const char *cName = sqlite3_column_name(stmt, i);
            NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
            //获得value的类型
            int type = sqlite3_column_type(stmt, i);
            switch (type) {
                case SQLITE_INTEGER:
                {
                    int number = sqlite3_column_int(stmt, i);
                    record[name] = @(number);
                    break;
                }
                case SQLITE_FLOAT:
                {
                    double doubleValue = sqlite3_column_double(stmt, i);
                    record[name] = @(doubleValue);
                }
                    break;
                case SQLITE3_TEXT:
                {
                    const char *textValue = sqlite3_column_text(stmt, i);
                    NSString *text = [NSString stringWithCString:textValue encoding:NSUTF8StringEncoding];
                    record[name] = text;
                }
                    break;
                case SQLITE_NULL:
                    record[name] = [NSNull new];
                    break;
                default:
                    break;
            }
        }
        [arrM addObject:record];
    }

事务

开启事务:begin transaction;
回滚事务:rollback;
提交事务:commit;

    //查询语句
    NSString *sql = @"insert into t_student(name,age) values (?,?)";
    NSArray *args = @[@"wanger",@(23)];
    sqlite3_stmt *stmt = nil;
    //sqlite3_prepare_v2()返回值等于SQLITE_OK,说明SQL语句已经准备成功,没有语法问题
    int result = (sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, nil));
    if (result == SQLITE_OK) {
        NSLog(@"");
    }
    
    /** 开启事务 */
    NSString *beginSql = @"BEGIN TRANSACTION";
    sqlite3_exec(db, beginSql.UTF8String, nil, nil, nil);
    
    for (int i = 0; i< 1000000; i++) {
        for (int i = 0; i<args.count; i++) {
            NSObject *objc = args[i];
            if ([objc isKindOfClass:[NSNumber class]]) {
                NSNumber *number = ( NSNumber *)objc;
                if (strcmp([number objCType], @encode(int))) {
                    sqlite3_bind_int(stmt, i + 1, number.intValue);
                }else if(strcmp([(NSNumber *)objc objCType], @encode(float))) {
                    sqlite3_bind_double(stmt, i + 1, number.doubleValue);
                }else if(strcmp([(NSNumber *)objc objCType], @encode(double))) {
                    sqlite3_bind_double(stmt, i + 1, number.doubleValue);
                }
            }else if([objc isKindOfClass:[NSString class]]){
                NSString *str = (NSString *)objc;
                /**
                 sqlite3_stmt*,
                 int:占位符的位置,第一个占位符的位置是1,不是0
                 const char*:占位符要绑定的值
                 int:在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
                 void(*)(void*):一个可选的函数回调,一般用于在语句执行后完成内存清理工作
                 */
                sqlite3_bind_text(stmt, i + 1, [str UTF8String], -1, SQLITE_TRANSIENT);
            }
        }
        /**
         执行SQL语句,返回SQLITE_DONE代表成功执行完毕
         */
        sqlite3_step(stmt);
        /**
         重置sqlite3_stmt *对象,返回SQLITE_OK代表重置成功
         */
        sqlite3_reset(stmt);

    }
    
    /** 提交事务 */
    NSString *commitsql = @"COMMIT TRANSACTION";
    int commitResult = sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
    if (commitResult == SQLITE_OK) {
        NSLog(@"--成功");
    }
    
    /**
     销毁sqlite3_stmt *对象,返回SQLITE_OK代表销毁成功
     */
    sqlite3_finalize(stmt);
    /** 开启事务 */
    NSString *sql = @"BEGIN TRANSACTION";
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    if (result == SQLITE_OK) {
        NSString *sql1 = @"update t_stu set money = money - 10 where name = 'zhangsan'";
        NSString *sql2 = @"update t_stu set money = money + 10 where name = 'lisi'";
        int result1 = sqlite3_exec(db, sql1.UTF8String, NULL, NULL, NULL);
        int result2 = sqlite3_exec(db, sql2.UTF8String, NULL, NULL, NULL);
        
        if (result1 == SQLITE_OK && result2 == SQLITE_OK) {
            /** 提交事务 */
            NSString *commitsql = @"COMMIT TRANSACTION";
            sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
        }else{
            /** 回滚事务 */
            NSString *commitsql = @"ROLLBACK TRANSACTION";
            sqlite3_exec(db, commitsql.UTF8String, nil, nil, nil);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读