zoukankan      html  css  js  c++  java
  • [转载]ios简单sqlite使用

    sqlite是嵌入式的和轻量级的sql数据库。sqlite是由c实现的。广泛用于包括浏览器(支持html5的大部分浏览器,ie除外)、ios、android以及一些便携需求的小型web应用系统。

    使用sqlite前的准备

    使用sqlite是很多做ios开发中第一次面对c的情况,包括我。因为sqlite是c写的,objc可以直接使用c代码。在sqlite前,一般都会使用cocoa touch框架,都是基于objc的。

    首先,需要在对应文件的头文件中加入:

    #import "/usr/include/sqlite3.h"

    并在Frameworks中加入所需的库,否则会报错:

    Undefined symbols:
      "_sqlite3_open", referenced from:

     

    加入库的方法是:

    image 

     

    选择sqlite库:

    image

    选择完的效果:

    image

    然后,应该有个成员变量,比如我的代码:

    @interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
        UIPopoverController *popoverController;
        UIToolbar *toolbar;
        id detailItem;
        UILabel *detailDescriptionLabel;
        sqlite3 *database;

    打开数据库

    sqlite数据库是文件数据库,是保存在文件系统中的。因此需要知道文件保存到哪里,可参见iOS中对文件的操作。比如本文保存到Documents目录下。代码:

    NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory
                                                       , NSUserDomainMask
                                                       , YES);
    NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];

    if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) {
        NSLog(@"open sqlite db ok.");
    }

    通过ssh查看Documents目录,发现mydb文件已经创建。sqlite的策略是如果有该文件就打开,如果没有就创建文件,也就是创建数据库。

    这里要注意,使用的是c语法,sqlite3_open传入的是database的地址。

    关闭数据库

    数据库使用完毕后,要关闭,比如退出应用的时候:

    - (void)viewDidUnload {
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
       sqlite3_close(database);
        self.popoverController = nil;
    }

    建表语句

    数据库打开以后,如果没有表,建表:

    char *errorMsg;
    const char *createSql="create table if not exists persons (id integer primary key autoincrement,name text)";

    if (sqlite3_exec(database, createSql, NULL, NULL, &errorMsg)==SQLITE_OK) {
        NSLog(@"create ok.");
    }

    这里要特别注意errorMsg传的是地址,因为该函数要通过地址引用来写报错字符信息。

    向表中插入记录

    和建表语句类似:

    const char *insertSql="insert into persons (name) values(‘张三’)";
        if (sqlite3_exec(database, insertSql, NULL, NULL, &errorMsg)==SQLITE_OK) {
            NSLog(@"insert ok.");
        }

    错误信息的处理

    如果在多个地方使用errorMsg,那么每次使用完毕要清空一下字串,比如这样:

    if (sqlite3_exec(database, createSql, NULL, NULL, &errorMsg)==SQLITE_OK) {
        NSLog(@"create ok.");
    }else {
        NSLog(@"error: %s",errorMsg);
        sqlite3_free(errorMsg);
    }

    查询结果集

    结果集的查询,需要用到statement:

    const char *selectSql="select id,name from persons";
    sqlite3_stmt *statement;
    if (sqlite3_prepare_v2(database, selectSql, -1, &statement, nil)==SQLITE_OK) {
        NSLog(@"select ok.");
    }

    while (sqlite3_step(statement)==SQLITE_ROW) {
        int _id=sqlite3_column_int(statement, 0);
        char *name=(char *)sqlite3_column_text(statement, 1);
        NSLog(@"row>>id %i, name %s",_id,name);
    }

    sqlite3_finalize(statement);

    不过这里有个问题,看看打印的日志:

    image

    乱码。因为直接用的char类型来做的。

    解决办法是,用nsstring替代char:

    while (sqlite3_step(statement)==SQLITE_ROW) {
        int _id=sqlite3_column_int(statement, 0);
        NSString *name=[[NSString alloc] initWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];
        NSLog(@"row>>id %i, name %@",_id,name);
    }

     

    char生成nsstring的时候做一次显式的编码。问题解决:

    image

    这说明:

    • 写入数据库,用char的方式没有问题,写入数据库的编码是对的;
    • 从库中取出,可能默认使用ascii解码,造成显示乱码。

    使用sqlite c api,要经常参考官方函数文档:http://www.sqlite.org/c3ref/funclist.html

  • 相关阅读:
    LeetCode Missing Number (简单题)
    LeetCode Valid Anagram (简单题)
    LeetCode Single Number III (xor)
    LeetCode Best Time to Buy and Sell Stock II (简单题)
    LeetCode Move Zeroes (简单题)
    LeetCode Add Digits (规律题)
    DependencyProperty深入浅出
    SQL Server存储机制二
    WPF自定义RoutedEvent事件示例代码
    ViewModel命令ICommand对象定义
  • 原文地址:https://www.cnblogs.com/zhwl/p/2845393.html
Copyright © 2011-2022 走看看