首页 > 代码库 > iOS数据存储之SqLite3

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