美文网首页
数据库sqilite学习二

数据库sqilite学习二

作者: 冷武橘 | 来源:发表于2020-07-21 14:42 被阅读0次

一、代码实现SQLite

1、打开数据库

   NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    NSString *sqlFilePath = [path stringByAppendingPathComponent:@"student.sqlite"];

    if ((SQLITE_OK ==  sqlite3_open(sqlFilePath.UTF8String, &_db))) {
          NSLog(@"数据库打开成功");
    }else
    {
        NSLog(@"数据库打开失败");
    }
  • 1、一个db就代表一个数据库
  • 2、 open会先判断数据库文件是否存在, 如果不存在会自动创建数据库文件, 然后再打开数据。
  • 3、 open会返回一个int类型的值, 这个值代表着打开数据库是否成功

2、 创建一个表

 const char *sql = "CREATE TABLE IF NOT EXISTS t_person(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL,age, score REAL DEFAULT 1);";
        char *error;
        sqlite3_exec(_db, sql, NULL, NULL, &error);
       /*
        参数
        1. 一个打开的数据库实例
        2. 需要执行的SQL语句, C语言的字符串
        3. SQL语句执行完毕后的回调,通常都传入 nil
        4. 回调函数的第1个参数,同样传入 nil
        5. 错误信息的字符串地址,通常传入 nil
        */

        if (error) {
            NSLog(@"创建表失败");
        }else
        {
            NSLog(@"创建表成功");
        }

3、DML语句-Insert

  NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student(age, name) VALUES (%.f, '%@');", 10.2 , @"eee"];
   sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);

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

sqlite3_exec()还可以执行的语句:
1、开启事务:begin transaction
2、提交事务:commit;
3、回滚事务:rollback;

  • 1、test:
     CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    for (int i=0; i<10000; i++) {
        NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student3(age, name) VALUES (%.f, '%@');", 10.2 , @"eee"];
        sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
    }
    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
    NSLog(@"%f",endTime-startTime);

打印可知前后用了5s左右

  • 2、test:
- (void)insertStudent{
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    [self beginTransaction];
    for (int i=0; i<10000; i++) {
        NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student3(age, name) VALUES (%.f, '%@');", 10.2 , @"eee"];
        sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
        
    }
    [self commitTransaction];
    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
    NSLog(@"%f",endTime-startTime);
}
- (void)beginTransaction{
     NSString *sql = @"begin transaction";
     sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
}

- (void) commitTransaction{
      NSString *sql = @"commit transaction";
      sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
}

打印可知前后只用了0.056582s左右,明显 效率提高 了10倍
测试分析:默认情况下执行 一条sqlite预计会自动开启事务和关闭事务。如果插入大量数据, 请要手动开启/提交事务。(因为默认执行一条sqlite语句自动开启事务和关闭事务是耗时的)。

  • 3、事务(Transaction)是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务,可以将逻辑相关的一组操作绑定在一起,保持数据的完整性。

COMMIT表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据库的更新写回到磁盘上的物理数据库中去,事务正常结束.

ROLLBACK表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有以完成的操作全部撤消,滚回到事务开始的状态。

4、DQL

    char *sql = "SELECT age, name FROM t_student3;";
    sqlite3_stmt *stmt; // 用于提取数据的变量

  // 第三个参数的长度, 传入-1系统自动计算
     /**
        1. db 数据库句柄
        2. SQL语句
        3. SQL语句的字节数,C语言字符串的长度,如果传入 -1,sqlite 3会自动计算
        4. `准备好语句`的句柄,后续处理查询结果,需要这个句柄
        5. 通常传入 nil
        */
    int result = sqlite3_prepare(db, sql, -1, &stmt, NULL);
    if (SQLITE_OK == result) {
        NSLog(@"准好了");
        // step方法会将数据提取到stmt中, 一次只能提取一条数据
        while (SQLITE_ROW == sqlite3_step(stmt)) {
            NSLog(@"提前到一条数据");
            const unsigned char * name = sqlite3_column_text(stmt, 0);
            int age = sqlite3_column_int(stmt, 1);
            NSLog(@"%s",name);
            NSLog(@"%d",age);
        }
     sqlite3_finalize(stmt);

    }
  • sqlite3_step()返回SQLITE_ROW代表遍历到一条新记录
  • sqlite3_column_*()用于获取每个字段对应的值,第2个参数是字段的索引,从0开始.

5、 预编译绑定-Insert

    NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student3(age, name) VALUES (?, ?);"];
    sqlite3_stmt *stmt; // 用于提取数据的变量
    int result = sqlite3_prepare(db, sql.UTF8String, -1, &stmt, NULL) == SQLITE_OK;
    if (result) {
        NSLog(@"预编译成功");
        
        // 第二个参数就是SQL中('?', ?)的位置, 注意: 从1开始
        sqlite3_bind_int(stmt, 1, 12);
        
        char  *s = "测试";
        sqlite3_bind_text(stmt, 2,  s, -1,  SQLITE_TRANSIENT);
        /*  第五个参数如果传入SQLITE_STATIC/nil, 那么系统不会保存需要绑定的数据, 如果需要绑定的数据提前释放了, 那么系统就随便绑定一个值(OC中直接传nil, 但是Swift传入nil会有大问题)
         第五个参数如果传入SQLITE_TRANSIENT, 那么系统会对需要绑定的值进行一次copy, 直到绑定成功之后再释放
         */
        
        //执行SQL语句
        if (sqlite3_step(stmt)== SQLITE_DONE) {
            NSLog(@"执行成功");
        }
        
        //重置STMT
        if( sqlite3_reset(stmt) != SQLITE_OK){
            NSLog(@"重置失败");
        }
        
         //注意点: 只要用到了stmt, 一定要关闭
        sqlite3_finalize(stmt);
  • 3 、test

- (void)inserTStudent{
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    [self beginTransaction];
    for (int i=0; i<10000; i++) {
        NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_student3(age, name) VALUES (?, ?);"];
        sqlite3_stmt *stmt; // 用于提取数据的变量
        int result = sqlite3_prepare(db, sql.UTF8String, -1, &stmt, NULL) == SQLITE_OK;
        if (result) {
            // NSLog(@"预编译成功");
            
            // 第二个参数就是SQL中('?', ?)的位置, 注意: 从1开始
            sqlite3_bind_int(stmt, 1, 12);
            
            char  *s = "测试";
            sqlite3_bind_text(stmt, 2,  s, -1,  SQLITE_TRANSIENT);
            /*  第五个参数如果传入SQLITE_STATIC/nil, 那么系统不会保存需要绑定的数据, 如果需要绑定的数据提前释放了, 那么系统就随便绑定一个值(OC中直接传nil, 但是Swift传入nil会有大问题)
             第五个参数如果传入SQLITE_TRANSIENT, 那么系统会对需要绑定的值进行一次copy, 直到绑定成功之后再释放
             */
            
            //执行SQL语句
            if (sqlite3_step(stmt)!= SQLITE_DONE) {
                NSLog(@"执行失败");
            }
            
            //重置STMT
            if( sqlite3_reset(stmt) != SQLITE_OK){
                NSLog(@"重置失败");
            }
            
            //注意点: 只要用到了stmt, 一定要关闭
            sqlite3_finalize(stmt);
        }
    }
    [self commitTransaction];
    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();
    NSLog(@"%f",endTime-startTime);
}
- (void)beginTransaction{
     NSString *sql = @"begin transaction";
     sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
}

- (void) commitTransaction{
      NSString *sql = @"commit transaction";
      sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL);
}

打印可知前后只用了0.04左右,可见使用准备语句开启/提交事务是目前最快的sqlite语句执行方式。

相关文章

网友评论

      本文标题:数据库sqilite学习二

      本文链接:https://www.haomeiwen.com/subject/vaeikktx.html