zoukankan      html  css  js  c++  java
  • ios之sqllite3简单使用

    SQLite3是嵌入在iOS中的关系型数据库,对于存储大规模的数据很有效。SQLite3使得不必将每个对象都加到内存中。

    基本操作:

    (1)打开或者创建数据库

    sqlite3 *database;
    int result = sqlite3_open("/path/databaseFile", &database);

    如果/path/databaseFile不存在,则创建它,否则打开它。如果result的值是SQLITE_OK,则表明我们的操作成功。

    注意上述语句中数据库文件的地址字符串前面没有@字符,它是一个C字符串。将NSString字符串转成C字符串的方法是:

    const char *cString = [nsString UTF8String];

    (2)关闭数据库

    sqlite3_close(database);

    (3)创建一个表格

    char *errorMsg;
    const char *createSQL = "CREATE TABLE IF NOT EXISTS PEOPLE (ID INTEGER PRIMARY KEY AUTOINCREMENT, FIELD_DATA TEXT)";
    int result = sqlite3_exec(database, createSQL, NULL, NULL, &errorMsg);

    执行之后,如果result的值是SQLITE_OK,则表明执行成功;否则,错误信息存储在errorMsg中。

    sqlite3_exec这个方法可以执行那些没有返回结果的操作,例如创建、插入、删除等。

    (4)查询操作

    NSString *query = @"SELECT ID, FIELD_DATA FROM FIELDS ORDER BY ROW";
    sqlite3_stmt *statement;
    int result = sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil);

    如果result的值是SQLITE_OK,则表明准备好statement,接下来执行查询:

    while (sqlite3_step(statement) == SQLITE_ROW) {
        int rowNum = sqlite3_column_int(statement, 0);
        char *rowData = (char *)sqlite3_column_text(statement, 1);
        NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];
        // Do something with the data here
    }
    sqlite3_finalize(statement);

    使用过其他数据库的话应该很好理解这段语句,这个就是依次将每行的数据存在statement中,然后根据每行的字段取出数据。

    (5)使用约束变量

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

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

    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);有三个参数:

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

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

    第三个参数是要加的值。

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

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

    这句,第四个参数代表第三个参数中需要传递的长度。对于C字符串来说,-1表示传递全部字符串。

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

    接下来,做个小例子吧!

    1、运行Xcode 4.3,新建一个Single View Application,名称为SQLite3 Test:

    2、连接SQLite3库:

    按照下图中的红色数字的顺序找到加号:

    单击这个加号,打开窗口,在搜索栏输入sqlite3:

    选择libsqlite3.dylib,单击Add,添加到工程。

    3、进行界面设计。打开ViewController.xib,使用Interface Builder设计界面如下:

    设置四个文本框的tag分别是1、2、3、4。

    4、在ViewController.h中添加属性和方法:

    @property (copy, nonatomic) NSString *databaseFilePath;
    
    - (void)applicationWillResignActive:(NSNotification *)notification;

    5、打开ViewController.m,向其中添加代码:

    5.1 在开头添加代码:

    #import "sqlite3.h"
    #define kDatabaseName @"database.sqlite3"

    5.2 在@implementation之后添加代码:

    @synthesize databaseFilePath;

    5.3 在viewDidLoad方法中添加代码:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        //获取数据库文件路径
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        self.databaseFilePath = [documentsDirectory stringByAppendingPathComponent:kDatabaseName];
        //打开或创建数据库
        sqlite3 *database;
        if (sqlite3_open([self.databaseFilePath UTF8String] , &database) != SQLITE_OK) {
            sqlite3_close(database);
            NSAssert(0, @"打开数据库失败!");
        }
        //创建数据库表
        NSString *createSQL = @"CREATE TABLE IF NOT EXISTS FIELDS (TAG INTEGER PRIMARY KEY, FIELD_DATA TEXT);";
        char *errorMsg;
        if (sqlite3_exec(database, [createSQL UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
            sqlite3_close(database);
            NSAssert(0, @"创建数据库表错误: %s", errorMsg);
        }
        //执行查询
        NSString *query = @"SELECT TAG, FIELD_DATA FROM FIELDS ORDER BY TAG";
        sqlite3_stmt *statement;
        if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK) {
            //依次读取数据库表格FIELDS中每行的内容,并显示在对应的TextField
            while (sqlite3_step(statement) == SQLITE_ROW) {
                //获得数据
                int tag = sqlite3_column_int(statement, 0);
                char *rowData = (char *)sqlite3_column_text(statement, 1);
                //根据tag获得TextField
                UITextField *textField = (UITextField *)[self.view viewWithTag:tag];
                //设置文本
                textField.text = [[NSString alloc] initWithUTF8String:rowData];
            }
            sqlite3_finalize(statement);
        }
        //关闭数据库
        sqlite3_close(database);
        //当程序进入后台时执行写入数据库操作
        UIApplication *app = [UIApplication sharedApplication];
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(applicationWillResignActive:)
         name:UIApplicationWillResignActiveNotification
         object:app];
    }

    5.4 在@end之前实现方法:

    //程序进入后台时的操作,实现将当前显示的数据写入数据库
    - (void)applicationWillResignActive:(NSNotification *)notification {
        //打开数据库
        sqlite3 *database;
        if (sqlite3_open([self.databaseFilePath UTF8String], &database)
            != SQLITE_OK) {
            sqlite3_close(database);
            NSAssert(0, @"打开数据库失败!");
        }
        //向表格插入四行数据
        for (int i = 1; i <= 4; i++) { 
            //根据tag获得TextField
            UITextField *textField = (UITextField *)[self.view viewWithTag:i];
            //使用约束变量插入数据
            char *update = "INSERT OR REPLACE INTO FIELDS (TAG, FIELD_DATA) VALUES (?, ?);";
            sqlite3_stmt *stmt;
            if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) == SQLITE_OK) {
                sqlite3_bind_int(stmt, 1, i);
                sqlite3_bind_text(stmt, 2, [textField.text UTF8String], -1, NULL);
            }
            char *errorMsg = NULL;
            if (sqlite3_step(stmt) != SQLITE_DONE)
                NSAssert(0, @"更新数据库表FIELDS出错: %s", errorMsg);
            sqlite3_finalize(stmt);
        }
        //关闭数据库
        sqlite3_close(database);
    }

    6、实现关闭键盘,参考《iOS开发4:关闭键盘》中的第2步。其中,backgroundTap方法如下:

    //关闭键盘
    - (IBAction)backgroundTap:(id)sender {
        for (int i = 1; i <= 4; i++) {
            UITextField *textField = (UITextField *)[self.view viewWithTag:i];
            [textField resignFirstResponder];
        }
    }

    7、运行程序:

    刚运行时显示如下面左图:

       

    在各个文本框输入内容,如上面右图。然后按Home键,这样,就执行了写入数据的操作。

    第一次运行程序时,在SandBox的Documents目录下出现数据库文件database.sqlite3:

    此时退出程序,再次运行,则显示的就是上次退出时的值。

  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/yulang314/p/3566854.html
Copyright © 2011-2022 走看看