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

原文地址:https://www.cnblogs.com/zanglitao/p/4095896.html