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

posted @ 2014-07-22 22:36  784692237  阅读(394)  评论(0编辑  收藏  举报