IOS开发-SQLite数据库

简单介绍

iOS中保存本地数据的方法有多种:Plist、NSUserDefault、NSKeyArchiver。然而这些方法有一个共性,就是只能用于存储少量的数据,如果需要存储大量的数据,使用这些方法就会存在很大的性能问题。

SQLite是一种轻量级的关系型数据库,由于它占用的资源非常少,主要用于作为移动端的数据库来使用,安卓和iOS使用的都是SQLite数据库,其SDK中均内置了SQLite驱动,可以很方便地调用相关接口(iOS中的SQLite框架是一个纯C的框架)。另外它的速度比MySql、PostgreSQL这两款注明的数据库还快。

关于图形化的数据库管理软件,可以使用fireFox浏览器中的一款插件:SQLiteManager。另外一款名为Navicat的软件,支持跨平台,支持大部分的主流数据库(包括SQLite),也是非常好用的。

对于关系型数据库,学过数据库的人都知道无非就是通过SQL语句对数据库进行增删改查操作。这里主要围绕这四种操作介绍iOS中SQLite的使用。

SQLite for iOS

首先在创建好的工程中添加SQLite3框架:

之后便可在项目中通过

#import <sqlite3>

引入框架。

相关界面设计如下:

代码如下:

#import "ViewController.h"
#import <sqlite3.h>

@interface ViewController ()
{
    sqlite3 *_db;  //申明数据库对象
}

@property (weak, nonatomic) IBOutlet UITextField *tfName;
@property (weak, nonatomic) IBOutlet UITextField *tfAge;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self mainOperation];
}

- (void)mainOperation{
    /*获取数据库路径*/
        NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *dbPath = [docPath stringByAppendingPathComponent:@"test.sqlite"];

    /*创建或打开数据库 指定目录下若不存在则创建*/
    if (sqlite3_open([dbPath UTF8String], &_db) == SQLITE_OK) {
        NSLog(@"database open");

        /*建表*/
        NSString *sqlCreateTable = @"create table if not exists student (id integer primary key autoincrement,name varchar(20),age interger)";
        if (sqlite3_exec(_db, [sqlCreateTable UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
            NSLog(@"table open successfully");
        }else{
            NSLog(@"Fail to create table!");
        }
    }
}

/*插入数据*/
- (IBAction)actionInsert:(id)sender {

    if (self.tfName.text.length != 0 && self.tfAge.text.length != 0) {
        NSString *sqlInsert = [NSString stringWithFormat:@"insert into student (name,age) values ('%@',%@)",self.tfName.text,self.tfAge.text];
        if (sqlite3_exec(_db, [sqlInsert UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
            NSLog(@"Insert successfully");
        }else{
            NSLog(@"Fail to insert!");
        }
    }
}

/*删除数据*/
- (IBAction)actionDelete:(id)sender {
    NSString *sqlDelete = @"delete from student where name='lotheve'";
    if (sqlite3_exec(_db, [sqlDelete UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
        NSLog(@"Delete successfully");
    }else{
        NSLog(@"Fail to delete!");
    }
}

/*更新数据*/
- (IBAction)actionUpdate:(id)sender {
    NSString *sqlDelete = @"update student set age='22' where name='lotheve'";
    if (sqlite3_exec(_db, [sqlDelete UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
        NSLog(@"Update successfully");
    }else{
        NSLog(@"Fail to update!");
    }
}

/*查询数据*/
- (IBAction)actionQuery:(id)sender {

    /*普通查询(指不需要对查询语句设置参数的查询*/
    //    NSString *sqlQuery = @"select * from student";
    //    sqlite3_stmt *stmt;
    //    if (sqlite3_prepare_v2(_db, [sqlQuery UTF8String], -1, &stmt, NULL) == SQLITE_OK) {
    //        //语句合法性检查成功,即查询语句准备完毕
    //        while (sqlite3_step(stmt) == SQLITE_ROW) {
    //            //遍历查询结果的每一行
    //            int _id = sqlite3_column_int(stmt, 0);
    //            const unsigned char *name = sqlite3_column_text(stmt, 1);
    //            int age = sqlite3_column_int(stmt, 2);
    //            NSLog(@"id:%d, name:%s, age:%d",_id,name,age);
    //        }
    //        NSLog(@"Query successfully");
    //    }
    //    //销毁sqlite3_stmt *对象
    //    sqlite3_finalize(stmt);

    /*有参查询*/
    NSString *sql = @"select * from student where age>?";
    int miniAge = 20;
    //封装绑定参数的方法
    sqlite3_stmt *stmt = [self execQueryWithSql:sql andParams:@[@(miniAge)]];
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        //遍历查询结果的每一行
        int _id = sqlite3_column_int(stmt, 0);
        const unsigned char *name = sqlite3_column_text(stmt, 1);
        int age = sqlite3_column_int(stmt, 2);
        NSLog(@"id:%d, name:%s, age:%d",_id,name,age);
    }
    NSLog(@"Query successfully");
    //销毁sqlite3_stmt *对象
    sqlite3_finalize(stmt);
}

/*!
 *  查询语句绑定参数
 */
- (sqlite3_stmt *)execQueryWithSql:(NSString *)sql andParams:(NSArray *)params{

    sqlite3_stmt *stmt;
    if (sqlite3_prepare_v2(_db, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK) {
        //依次绑定参数
        for (int i = 1; i<= params.count; i++) {
            id obj = params[i-1];
            if (obj == nil) {
                //参数为nil
                sqlite3_bind_null(stmt, i);
            }else if ([obj isKindOfClass:[NSNumber class]]){
                //参数为NSNumer对象
                const char *numType = [(NSNumber *)obj objCType];
                if (strcmp(numType, @encode(int)) == 0) {
                    sqlite3_bind_int(stmt, i, [obj intValue]);
                }else if (strcmp(numType, @encode(double)) == 0 || strcmp(numType, @encode(float)) == 0){
                    sqlite3_bind_double(stmt, i, [obj doubleValue]);
                }else{
                    stmt = NULL;
                }
            }else if ([obj isKindOfClass:[NSString class]]){
                //参数类型为字符串
                sqlite3_bind_text(stmt, i, [obj UTF8String], -1, NULL);
            }else{
                stmt = NULL;
            }
        }
        return stmt;
    }

    return NULL;
}

@end

主要涉及到的几个函数:

 1.打开数据库
 int sqlite3_open(
 const char *filename,   // 数据库的文件路径
 sqlite3 **ppDb          // 数据库实例
 );


 2.执行任何SQL语句
 int sqlite3_exec(
 sqlite3*,                                  // 一个打开的数据库实例
 const char *sql,                           // 需要执行的SQL语句
 int (*callback)(void*,int,char**,char**),  // SQL语句执行完毕后的回调
 void *,                                    // 回调函数的第1个参数
 char **errmsg                              // 错误信息
 );

 3.检查SQL语句的合法性(用于查询前的准备)
 int sqlite3_prepare_v2(
 sqlite3 *db,            // 数据库实例
 const char *zSql,       // 需要检查的SQL语句
 int nByte,              // SQL语句的最大字节长度,通常用-1表示(系统会自动计算),也可以用strlength函数计算
 sqlite3_stmt **ppStmt,  // sql_stmt对象 (执行的对象),用来获得数据库数据
 const char **pzTail     // 未执行的sql语句
 );

 4.查询一行数据
 int sqlite3_step(sqlite3_stmt*); // 如果查询到一行数据,就会返回SQLITE_ROW

 5.绑定查询语句参数
 sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*))
 绑定字符串的参数有5个参数,大部分绑定参数函数只有3个参数
 (1)第1个参数是sqlite3_stmt *类型
 (2)第2个参数指占位符的位置,第一个占位符的位置是1,不是0
 (3)第3个参数指占位符要绑定的值
 (4)第4个参数指在第3个参数中所传递数据的长度,对于C字符串,可以传递-1代替字符串的长度
 (5)第5个参数是一个可选的函数回调,一般用于在语句执行后完成内存清理工作

表student结构及“年龄>20”的查询结果如下:

参考文档:
《iOS开发数据库篇—SQLite简单介绍》
《IOS数据存储之SQLite详解》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值