您的位置:首页 > 数据库

IOS开发-SQLite数据库

2016-03-07 20:21 363 查看

简单介绍

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详解》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios开发 数据库 SQLite