zoukankan      html  css  js  c++  java
  • iOS数据存储之SqLite3

    iOS中数据存储的方式有很多中,当数据量较大的时候偏好设置,归档和plist就无法满足需求了

    这时候就需要用SqLite或者CoreData来存储数据

    下面就来介绍一下如何使用SqLite存储数据

    要使用Sqlite必须引入libSqlite3.dylib库

    要使用首先要有一个handle句柄(handle句柄,在C语言中,通常把用于控制某类东西的叫做句柄,实际上是一个指针。)

    // 数据库句柄
        sqlite3 *_db;

    SqLite存储数据时也是存在一个文件中的,只不过这个文件格式是定制的,可以让SqLite快速查询到其需要的数据

    所以如果要使用SqLite数据库首先要创建一个数据库文件,所以要有一个文件路径

    // 一个NSString分类
    - (NSString *)appendDocumentDir
    {
        NSString *docDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    
        return [docDir stringByAppendingPathComponent:self];
    }
        // 设置沙盒中的文件路径
        // 提示:在自己开发中,不要用.db结尾的sqlite数据库文件名
        NSString *dbPath = [@"readme.db" appendDocumentDir];
        NSLog(@"%@", dbPath);

    上面创建了我们存储数据库文件的路径dbPath

    下面我们就开始创建这个存储文件

    /**
         sqlite3_open
         
         1) 如果数据库存在,直接打开
         2) 如果数据库不存在,先创建数据库文件,再打开
         */
        _db = NULL;
        
        if (SQLITE_OK == sqlite3_open([dbPath UTF8String], &_db)) {
            NSLog(@"数据库打开成功");
        } else {
            NSLog(@"数据库打开失败");
        }

    调用sqlite3_open函数就会创建或者打开一个数据库,如果指定路径已经存在数据库就会打开这个数据库,如果指定的dbPath不存在数据库就会创建一个数据库然后打开,创建或者打开的时候一是要传入路径,二是要传入句柄,因为后面的数据库增删改查都要靠句柄来干活.

    上面代码中的SQLITE_OK是SqLite操作结果的返回码,具体含义可以参照头文件或者帮助文档

    此时我们就有了一个可以操作的数据库了,有了数据库以后第一件事肯定是建一张表

    #pragma mark 创建数据表
    - (void)createTable
    {
        // 避免重复建表的思路
        // 1. 检查沙盒,判断数据库文件是否存在,如果存在就不再建表;
        // 2. 数据库的方法:IF NOT EXISTS,放在表名之前即可
        // 定义SQL语句
        NSString *sql = @"CREATE TABLE IF NOT EXISTS T_Person (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, gender INTEGER, age INTEGER, height REAL)";
    
        [self execSQL:sql message:@"创建数据表"];
    }
    
    #pragma mark 单步执行SQL
    - (void)execSQL:(NSString *)sql message:(NSString *)message
    {
        // 执行SQL语句
        /**
         1> 数据库句柄
         2> 要执行的SQL语句
         3> 回调:SQL指令执行完成后,调用的函数,就叫做回调函数
         4> 回调函数的第一个参数
         5> SQL语句执行的出错信息
         */
        char *errmsg = NULL;
        if (SQLITE_OK == sqlite3_exec(_db, [sql UTF8String], NULL, NULL, &errmsg)) {
            NSLog(@"%@成功!", message);
        } else {
            // C语言中字符串输出应该用%s
            NSLog(@"%@失败 - %s", message, errmsg);
        }
    }

    第一个方法是创建好建表语句,然后交给第二个我方法去执行建表操作

    关于建表语句:CREATE TABLE IF NOT EXISTS没有这张表时才创建,如果有问题会及时发现

           表名称一般以T_开头,防止与关键字或者类名变量名冲突

    sqlite3_exec函数可以执行SQL语句,从而对数据库进行操作

    第一个参数是操作数据库用的句柄,第二个参数是执行的sql语句,第三四个参数是回调相关的参数,最后一个是错误信息

    如果打印出成功信息建表就成功了.

    然后增删改功能照着上面的代码写好SQL语句,直接调用就可以了,下面看看查询时该怎么写代码

    - (void)allPersons
    {
        // 1. SQL
        NSString *sql = @"SELECT id, name, age, gender, height FROM T_Person";
        
        // 2. 查询语句通常是使用字符串拼接出来的
        // 因此,在正常使用查询语句之前,需要检查SQL语句的语法正确!
        sqlite3_stmt *stmt = NULL;
        
        if (SQLITE_OK == sqlite3_prepare_v2(_db, [sql UTF8String], -1, &stmt, NULL)) {
            NSLog(@"语法正确");
            // 利用句柄,逐一查询符合条件的数据
            // sqlite3_step 每次提取一条查询的记录行,不断重复,一直取到最后一条记录位置
            while (SQLITE_ROW == sqlite3_step(stmt)) {
                // 取到行信息,逐一获取每一列的内容
                // iCol对应的就是SQL语句中字段的顺序,从0开始
                // 根据实际查询字段的属性,使用sqlite3_column_xxx取得对应的内容即可
                int ID = sqlite3_column_int(stmt, 0);
                const unsigned char *name = sqlite3_column_text(stmt, 1);
                int age = sqlite3_column_int(stmt, 2);
                int gender = sqlite3_column_int(stmt, 3);
                CGFloat height = sqlite3_column_double(stmt, 4);
                
                // const unsigned char *直接输出看不出结果,需要转换
                NSString *nameUTF8 = [NSString stringWithUTF8String:(const char *)name];
                
                Person *p = [Person personWithID:ID name:nameUTF8 age:age gender:gender height:height];
                
                NSLog(@"%@", p);
            }
        } else {
            NSLog(@"语法错误");
        }
    }

    查询的时候基本步骤就是:1.创建查询语句

               2.创建sqlite3_stmt结果集

               3.用sqlite3_prepare_v2函数建立结果集和操作句柄之间的关系,并且检查语法

               4.while (SQLITE_ROW == sqlite3_step(stmt)) 循环判断并且从中取出数据

               5.sqlite3_column_int(stmt, 0);用类似函数取出数据,第二个参数是所在

    其他关于数据库主键,外键和其他约束的请查阅sqlite资料

    另外有一个SQLite的第三方类库FMDB,有兴趣的可以去github上搜一下     

    x

  • 相关阅读:
    SQL server 插入不同IP的数据库
    SQL Server中的循环例子(网摘)
    C#小型数据库只能查询
    vue.prototype和vue.use的区别和注意点
    Ajax+PHP简单入门教程
    smarty在windows下的安装
    docker安装mysql镜像和容器
    Linux导出未越狱Iphone10.3QQ聊天记录
    记一次Struts中文乱码
    Ubuntu设置服务开机启动
  • 原文地址:https://www.cnblogs.com/xyzaijing/p/3861563.html
Copyright © 2011-2022 走看看