zoukankan      html  css  js  c++  java
  • IOS存储(1)使用sqlite3

    sqlite3是纯C语言的库,我们需要使用C语法使用它,使用过程如下:

    1:工程添加sqlite3.0.sqlite,它总是代表最新的sqlite3的库;类中添加#import <sqlite3.h>

    2:使用sqlite3_open打开数据库

    3:对于无返回值的sql操作,使用sqlite3_exec函数

    4:对于有返回值的查询操作,首先使用sqlite3_prepare_v2预编译,将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt,该结构体中包含了将要执行的的SQL语句的信息),使用sqlite3_bind_xxx进行参数绑定,然后使用sqlite3_step依此得到查询结果每一行数据,通过sqlite3_column_xxx 取出数据,最后释放句柄

    打开或者创建数据库

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        NSString *dbPath = [dirPath stringByAppendingPathComponent:@"mydb.db"];
        
        NSLog(@"%@",dbPath);
        //如果有数据库则直接打开,否则创建并打开(注意filePath是ObjC中的字符串,需要转化为C语言字符串类型)
        if(SQLITE_OK != sqlite3_open(dbPath.UTF8String, &_database)) {
            NSLog(@"error open");
        }
        
        //sqlite3_close(_database);
    }

    代码执行后沙盒document目录下会多出一个mydb.db文件,我们可以通过终端在沙盒document目录下执行sqlite3 mydb.db 命令查看db内容

    添加数据库表

    - (IBAction)createDBTable:(id)sender {
        const char *createSQL = "create table user(id integer primary key autoincrement,name text,gender text,address text)";
        char *error;
        if(SQLITE_OK != sqlite3_exec(_database, createSQL, NULL, NULL, &error)) {
            NSLog(@"error create");
         sqlite3_free(error); } }

     sqlite3支持以下五种格式数据:

     NULL: 表示该值为NULL值。

     INTEGER: 无符号整型值。

     REAL: 浮点值。

     TEXT: 文本字符串,存储使用的编码方式为UTF-8、UTF-16BE、UTF-16LE。

     BLOB: 存储二进制数据

    在终端执行.tables和.schema user可以查看当前数据库拥有的表以及表结构

    添加数据

    - (IBAction)saveObj:(id)sender {
        NSString *sqlStr = [NSString stringWithFormat:@"insert into user(name,gender,address) values ('%@','%@','%@')",@"zaglitao",@"gender",@"浙江"];
        const char *saveSQL = sqlStr.UTF8String;
        
        char *error;
        if(SQLITE_OK != sqlite3_exec(_database, saveSQL, NULL, NULL, &error)) {
            NSLog(@"error create");
         sqlite3_free(error); } }

     在终端执行select * from user可以查看添加的数据

    修改数据

    - (IBAction)changeObj:(id)sender {
        NSString *sqlStr = [NSString stringWithFormat:@"update user set name='%@',address='%@' where name='%@'",@"zanglitao",@"杭州",@"zaglitao"];
        const char *updateSQL = sqlStr.UTF8String;
        
        char *error;
        if(SQLITE_OK != sqlite3_exec(_database, updateSQL, NULL, NULL, &error)) {
            NSLog(@"error create");
         sqlite3_free(error); } }

    删除数据

    - (IBAction)deleteObj:(id)sender {
        NSString *sqlStr = [NSString stringWithFormat:@"delete from user where name='%@'",@"zanglitao"];
        const char *deleteSQL = sqlStr.UTF8String;
        
        char *error;
        if(SQLITE_OK != sqlite3_exec(_database, deleteSQL, NULL, NULL, &error)) {
            NSLog(@"error create");
         sqlite3_free(error); } }

    上面的4中操作除了sql语句不同,执行的逻辑完全一致,我们自己使用时可以进行统一的封装,其中用到的关键函数sqlite3_exec:

    SQLITE_API int sqlite3_exec(
      sqlite3*,                                  /* An open database */
      const char *sql,                           /* SQL to be evaluated */
      int (*callback)(void*,int,char**,char**),  /* Callback function */
      void *,                                    /* 1st argument to callback */
      char **errmsg                              /* Error msg written here */
    );

    这个接口是最常用到的,几乎除了查询之外的 sql 命令都可以用它来操作,比如创建表,插入/更新/删除记录,创建/提交/回滚事务等。

    注意:如果 errmsg 不为 null,那么当错误发生时, sqlite 就会为错误消息分配内存,返回给调用者,调用者有责任调用 sqlite3_free 来释放这部分内存。

    事务相关的操作也可以使用这个方法执行,具体语句如下:

    创建事务的语句:BEGIN EXCLUSIVE TRANSACTION;

    提交事务的语句:COMMIT TRANSACTION;

    回滚事务的语句:ROLLBACK TRANSACTION;

    除了上面只执行一句sql语句,不需要任何返回值的数据库操作外,还有另一种最常用的数据库操作:读取

    - (IBAction)getObjs:(id)sender {
        const char *sql = "select * from user where name like ?";
        sqlite3_stmt *stmt;
        
        //预编译sql语句,stmt保留了预编译结果的引用
        int quertResult = sqlite3_prepare_v2(_database, sql, -1, &stmt, NULL);
        //预编译成功
        if (quertResult == SQLITE_OK) {
            //参数绑定
            sqlite3_bind_text(stmt, 1, "zanglitao", -1, NULL);
            
            //sqlite3_step() has another row ready
            while (sqlite3_step(stmt) == SQLITE_ROW) {
                //取出查询结果集
                
                //列数
                int columnCount = sqlite3_column_count(stmt);
                for (int i = 0; i < columnCount; i++) {
                    const char *columnname = sqlite3_column_name(stmt, i);
                    const unsigned char *columnvalue = sqlite3_column_text(stmt, i);
                    
                    NSLog(@"%@:%@",[NSString stringWithUTF8String:columnname],[NSString stringWithUTF8String:columnvalue]);
                }
                
            }
        }
        sqlite3_finalize(stmt);
    }

    2014-11-13 20:41:58.717 DataStoreDemo[1781:607] id:6

    2014-11-13 20:41:58.718 DataStoreDemo[1781:607] name:zanglitao

    2014-11-13 20:41:58.718 DataStoreDemo[1781:607] gender:gender

    2014-11-13 20:41:58.719 DataStoreDemo[1781:607] address:杭州

     

    因为sqlite3使用c语法,不如oc来得简洁,开发中常常会对sqlite3进行封装,当然也可以选择第三方优秀的库,当前比较流行的sqlite3封装库是FMDB,FMDB使用十分方便,具体教程可以查看GitHub

  • 相关阅读:
    O(big oh) (big omega) (big theta)
    Ex 7_21 在一个流网络中,一条边被称为是临界的...第十三次作业
    Ex 7_17 考虑如下的网络(其中数字为对应边的容量)...第十三次作业
    Expm 10_2 实现Ford-Fulkerson算法,求出给定图中从源点s到汇点t的最大流,并输出最小割。
    pat1009
    pat1008
    pat1007
    pat1006
    pat1005
    pat1004
  • 原文地址:https://www.cnblogs.com/zanglitao/p/4095896.html
Copyright © 2011-2022 走看看