iOS 数据存储之SQLite3的使用

SQLite3是iOS内嵌的数据库,SQLite3在存储和检索大量数据方面很是有效,它使得没必要将每一个对象都加到内存中。还可以对数据进行负责的聚合,与使用对象执行这些操做相比,得到结果的速度更快。sql

SQLite3使用SQL结构化查询语言,SQL是与关系数据库交互的标准语言。数据库

SQLite3的使用:api

一、导入头文件

#import <sqlite3.h>函数

二、建立或者打开数据库

   //建立和打开数据库
    sqlite3 *database;
    
    //若是sqlite3_open的结果是 SQLITE_OK,表示数据库已经打开成功。
    //SQLite3是采用可移植的C,数据库的文件路径必须以C字符串(非NSString)的形式进行传递。
    if (sqlite3_open("/path/databaseFile", &database) != SQLITE_OK) 
{
     sqlite3_close(database); NSAssert(
0, @"Failed to open database");
  }

三、建立一个表

    //建立一个新表
    NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS "
    "(ROW INTEGER PRIMARY KEY, FIELD_DATA TEXT);";
    char *errorMsg;
    
    //sqlite3_exec 针对 SQLite3 运行任何不返回数据的命令
    if (sqlite3_exec (database, [createSQL UTF8String],
                      NULL, NULL, &errorMsg) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Error creating table: %s", errorMsg);
    }

注:sqlite3_exec 执行以后,若是值是SQLITE_OK,则代表执行成功;不然,错误信息存储在errorMsg中。lua

sqlite3_exec这个方法能够执行那些没有返回结果的操做,例如建立、插入、删除等。spa

四、对表进行操做

4.1存储数据到数据库

  
    sqlite3 *database;
    if (sqlite3_open([[self dataFilePath] UTF8String], &database)
        != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(0, @"Failed to open database");
    }

     //例子:存储UITextField的值到数据库
    for (int i = 0; i < 4; i++) {
        UITextField *field = self.lineFields[i];
        
        //插入操做
        char *update = "INSERT OR REPLACE INTO FIELDS (ROW, FIELD_DATA) "
        "VALUES (?, ?);";
        char *errorMsg = NULL;
        //建立stmt
        sqlite3_stmt *stmt;
        //不管针对哪一种数据,任何绑定函数的第一个参数都指向以前在sqlite3_prepare_v2 调用中 使用的sqlite3_stmt
        if (sqlite3_prepare_v2(database, update, -1, &stmt, nil)
            == SQLITE_OK) {
            
            //SQLITE_OK 表示执行成功
            
            /*sqlite3_bind_int(stmt, 1, i);有三个参数:
            
            第一个是sqlite3_stmt类型的变量,在以前的sqlite3_prepare_v2中使用的。
            
            第二个是所约束变量的标签index。
            
            第三个参数是要加的值。*/
            
            sqlite3_bind_int(stmt, 1, i);
            sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL);
        }
        
        if (sqlite3_step(stmt) != SQLITE_DONE)
            NSAssert(0, @"Error updating table: %s", errorMsg);
        
        //sqlite3_finalize销毁前面被sqlite3_prepare建立的准备语句
        sqlite3_finalize(stmt);
    }
    //sqlite3_close关闭前面使用sqlite3_open打开的数据库链接,任何与这个链接相关的准备语句必须在调用这个关闭函数以前被释放
    sqlite3_close(database);

4.2 对数据库进行查询操做

 

    //建立query 和 sqlite3_stmt
    NSString *query = @"SELECT ROW, FIELD_DATA FROM FIELDS ORDER BY ROW";
    sqlite3_stmt *statement;
    
    //不管针对哪一种数据,任何绑定函数的第一个参数都指向以前在sqlite3_prepare_v2 调用中 使用的sqlite3_stmt
    if (sqlite3_prepare_v2(database, [query UTF8String],
                           -1, &statement, nil) == SQLITE_OK)
    {
         //sqlite3_step用于执行有前面sqlite3_prepare建立的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回
        while (sqlite3_step(statement) == SQLITE_ROW) {
            int row = sqlite3_column_int(statement, 0);
            char *rowData = (char *)sqlite3_column_text(statement, 1);
            
NSString
*fieldValue = [[NSString alloc] initWithUTF8String:rowData]; UITextField *field = self.lineFields[row]; field.text = fieldValue;
}
//sqlite3_finalize销毁前面被sqlite3_prepare建立的准备语句 sqlite3_finalize(statement); } //sqlite3_close关闭前面使用sqlite3_open打开的数据库链接,任何与这个链接相关的准备语句必须在调用这个关闭函数以前被释放 sqlite3_close(database);

五、使用约束变量

实际操做时常用叫作约束变量的东西来构造SQL字符串,从而进行插入、查询或者删除等。指针

例如,要执行带两个约束变量的插入操做,第一个变量是int类型,第二个是C字符串:code

char *sql = "insert into oneTable values (?, ?);";
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK) {
    sqlite3_bind_int(stmt, 1, 235);
    sqlite3_bind_text(stmt, 2, "valueString", -1, NULL);
}
if (sqlite3_step(stmt) != SQLITE_DONE)
    NSLog(@"Something is Wrong!");
sqlite3_finalize(stmt);

这里,sqlite3_bind_int(stmt, 1, 235);有三个参数:sqlite

第一个是sqlite3_stmt类型的变量,在以前的sqlite3_prepare_v2中使用的。对象

第二个是所约束变量的标签index。

第三个参数是要加的值。

有一些函数多出两个变量,例如

sqlite3_bind_text(stmt, 2, "valueString", -1, NULL);

这句,第四个参数表明第三个参数中须要传递的长度。对于C字符串来讲,-1表示传递所有字符串。

第五个参数是一个回调函数,好比执行后作内存清除工做。

 

六、SQLite3中经常使用的函数

sqlite3_open():打开数据库,在操做数据库以前,首先要打开数据库。这个函数打开一个sqlite数据库文件的链接而且返回一个数据库链接对象。这个操做同时程序中的第一个调用的sqlite函数,同时也是其余sqlite api的先决条件。许多的sqlite接口函数都须要一个数据库链接对象的指针做为它们的第一个参数。

sqlite3_prepare():将sql文本转换成一个准备语句(prepared statement)对象,同时返回这个对象的指针。这个接口须要一个数据库链接指针以及一个要准备的包含SQL语句的文本。它实际上并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句。

sqlite3_step():执行有前面sqlite3_prepare建立的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_setp()。继续调用sqlite3_setp()知道这个语句完成,那些不返回结果的语句(如:INSERT,UPDATE,或DELETE),sqlite3_step()只执行一次就返回。

sqlite3_column():执行sqlite3_step()执行一个准备语句获得的结果集的当前行中返回一个列。每次sqlite3_step获得一个结果集的列停下后,这个过程就能够被屡次调用去查询这个行的各列的值。对列操做是有多个函数,均以sqlite3_column为前缀。

sqlite3_finalize():销毁前面被sqlite3_prepare建立的准备语句,每一个准备语句都必须使用这个函数去销毁以防止内存泄露。在空指针上调用这个函数没有什么影响,同时能够准备语句的生命周期的任一时刻调用这个函数:在语句被执行前,一次或屡次调用sqlite_reset以后,或者在sqlite3_step任何调用以后无论语句是否完成执行

sqlite3_close():关闭前面使用sqlite3_open打开的数据库链接,任何与这个链接相关的准备语句必须在调用这个关闭函数以前被释放

相关文章
相关标签/搜索