IOS 数据存储之 SQLite详解

  在IOS开发中经常会需要存储数据,对于比较少量的数据可以采取文件的形式存储,比如使用plist文件、归档等,但是对于大量的数据,就需要使用数据库,在IOS开发中数据库存储可以直接通过SQL访问数据库,也可以通过ORM进行对象关系的映射,当然也可以选择使用第三方框架实现对数据库的操作。在这里,主要来讲解一下第一种方式,SQLite。

SQLite

  数据库有很多,分为重量级和轻量级两类,移动设备的内存比较小,因此需要选择轻量级的数据库。在移动设备上应用程序开发中使用数据库,比较主流的是SQLite。SQLite支持跨平台,虽然是轻量级的数据库,但是它的功能很强大,其功能不亚于很多大型的关系数据库。

  SQLite基于C语言开发的轻型数据库,因此需要使用C语言语法进行数据库操作、访问,不能直接使用OC语言访问数据库。此外,SQLite中采用的是动态数据类型,即使创建时定义了一种类型,在实际操作时也可以存储其他类型,但是推荐建库时使用合适的类型,特别是应用需要考虑跨平台的情况时。

  SQLite可以直接在代码中使用,但是在开发的过程中,最好安装一个可以直接打开数据库的工具,来验证对数据库的操作是否正确,方便程序调试。大家可以去SQLite官方网站下载Mac OSX系统下的命令行工具,也可以使用类似于SQLiteManager、MesaSQLite等工具。

  数据库的使用,主要包括对数据库的打开关闭、创建表格、对数据库中的数据进行增删改查以及更新等操作,实际上也就是通常所讲的SQL语句,SQLite中的SQL语法并没有太大的差别,因此这里对于SQL语句的内容不过多赘述,大家可以参考其他SQL相关的内容,在这里,我们来详细讲解一下在IOS开发中的SQLite的使用。

SQLite使用步骤:

  1. 在项目中导入libsqlite3.0.dylib框架

  2. 获取数据库的路径,一般是获得获得沙盒中Document文件夹路径,然后拼接得到数据库路径

  3. 创建或者打开数据库,需要注意的是,在打开的时候需要使用C语言,因此需要先将路径转为C的字符串,然后通过sqlite3_open()打开数据库,如果文件存在则直接打开,否则创建并打开。根据sqlite3_open()返回值来判断是否正确成功打开,如果成功打开,就可以使用得到的sqlite3类型的对象,来对数据库进行其他操作。

  4. 执行写好的SQL语句,对数据库进行操作,执行SQL语句有两种,一种是无返回值语句,比如创建、增加、删除等,一种是有返回值的语句,比如查询。

(1). 对于无返回值的语句(如增加、删除、修改等)直接通过sqlite3_exec()函数执行,因此可以封装一个方法,用于除查询以外的操作

(2). 对于有返回值的语句则首先通过sqlite3_prepare_v2()进行sql语句评估(语法检测),然后通过sqlite3_step()依次取出查询结果的每一行数据,对于每行数据都可以通过对应的sqlite3_column_类型()方法获得对应列的数据,如此反复循环直到遍历完成。当然,最后需要释放句柄。

  5. SQLite操作是持久连接,在整个操作过程中无需管理数据库连接,如果使用完毕,可以选择通过sqlite3_close()手动关闭数据库

SQLite使用代码

  导入框架,如图所示

//  ViewController.m
//  JRSQLite查询3
//
//  Created by jerehedu on 15/6/16.
//  Copyright (c) 2015年 jerehedu. All rights reserved.
//

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

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

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 获得数据库路径
    // 获得沙盒中Document文件夹路径
    NSString *dbPath = [self getUserDocumentPath];
    // 拼接得到数据库路径
    NSString *sqlitePath = [dbPath stringByAppendingPathComponent:@"test.sqlite"];

    // 创建或打开数据库
    const char *p = [sqlitePath UTF8String];
    int res = sqlite3_open(p, &db);
    if (res==SQLITE_OK) {
        NSLog(@"db open");

        //<一>创建表格
        NSString *sql = @"create table if not exists temps (t_id integer primary key autoincrement,t_name varchar(20) )";
        if ([self execNoQueryWithSQL:sql]) {
            NSLog(@"table temps is created");
        }

        //<二>插入数据
        NSString *insert_Sql = @"insert into temps (t_name) values ('pear')";
        if ([self execNoQueryWithSQL:insert_Sql]) {
            NSLog(@"table insert ");
        }

        //<三>删除数据
        NSString *delete_sql = @"delete from temps where t_id=2";
        if ([self execNoQueryWithSQL:delete_sql]) {
            NSLog(@"table delete ");
        }

        //<四>修改数据
        NSString *update_sql = @"update temps set t_name='ios' where t_id=1";
        if ([self execNoQueryWithSQL:update_sql]) {
            NSLog(@"table update ");
        }

        //<五>查询简单的数据1
        NSString *select_sql1 = @"select * from temps where t_id=1";
        sqlite3_stmt *stmt1 = [self execQueryWithSQL:select_sql1];
        while (sqlite3_step(stmt1) == SQLITE_ROW) {
            //按照当前列的类型选数据,列数从0开始
            int t_id = sqlite3_column_int(stmt1, 0);
            const unsigned char *t_name = sqlite3_column_text(stmt1, 1);
            NSString *name = [NSString stringWithUTF8String:(char*)t_name];
            NSLog(@"%i %@",t_id,name);
        }
        //释放stmt statement
        sqlite3_finalize(stmt1);

        //<五>查询数据2 参数化的sql语句  查找id>2 并且名字以p开头的
        //用?占位
        int seachId2 = 2;
        NSString *seach_name = @"p%";
        NSString *seach_sql = @"select * from temps where t_id>? and t_name like ?";
        sqlite3_stmt *stmt6 = [self execQueryWithSQL:seach_sql andWithParams:@[[NSNumber numberWithInt:seachId2],seach_name]];

        //准备执行(相当于点击run query),执行的时候是一行一行的执行
        while (sqlite3_step(stmt6) == SQLITE_ROW) {
            //按照当前列的类型选数据,列数从0开始
            int t_id = sqlite3_column_int(stmt6, 0);
            const unsigned char *t_name = sqlite3_column_text(stmt6, 1);
            NSString *name = [NSString stringWithUTF8String:(char*)t_name];
            NSLog(@"..>>>>>>...%i %@",t_id,name);
        }

        sqlite3_finalize(stmt6);
    }

    // 关闭数据库
    sqlite3_close(db);
}

#pragma mark - 获得沙盒sandbox里面document文件夹路径
- (NSString *)getUserDocumentPath
{
    NSArray *path  = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [path firstObject];
    return documentPath;
}

#pragma mark - 执行除查找以外的数据库操作方法
-(BOOL)execNoQueryWithSQL:(NSString*)sql
{
    /*
     执行
     参数1:sqlite3 对象
     参数2:c形式的 sql语句
     参数3:回调函数
     参数4:回调函数的参数
     参数5:错误信息(可以char类型指针接受错误信息,用来查错使用)
     */
    if (sqlite3_exec(db, [sql UTF8String], NULL, NULL, NULL) == SQLITE_OK) {
        return YES;
    }
    return NO;
}

#pragma mark 返回查询结果集(简单无参)
-(sqlite3_stmt *)execQueryWithSQL:(NSString*)sql
{
    //执行sql语句之后,返回的结果语句
    sqlite3_stmt *stmt;
    /*
     准备执行查询的sql语句 (相当于把查询语句写好)
     参数3:sql语句长度,通常用-1表示(系统会自动计算),也可以用strlength函数计算
     参数4:sql_stmt对象 (执行的对象)
     参数5:未执行的sql语句
     */
    int pre_res = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    //如果准备成功
    if (pre_res == SQLITE_OK) {
        return stmt;
    }
    return NULL;
}

#pragma mark - 返回查询结果集(有参数的)
-(sqlite3_stmt *)execQueryWithSQL:(NSString *)sql andWithParams:(NSArray *)params
{
    sqlite3_stmt *stmt;
    int pre_res = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);
    if (pre_res == SQLITE_OK) {
        //有参数,循环绑定参数
        if (params!=nil) {
            for (int i=0; i<params.count; i++) {

                id obj = params[i];
                //绑定的数据类型可能为NSString或者NSNumber,或者数据为空,分别判断
                if (obj==nil) {
                    //如果数据为nil
                    sqlite3_bind_null(stmt, i+1);
                }
                else if ([obj respondsToSelector:@selector(objCType)])
                {
                    //当前的绑定的数据类型位NSNumber
                    //NSNumber判断包装的是int?longInt?shortInt?float?double?
                    /*
                     strstr(参数1,参数2) (strstr() c中函数搜索一个字符串在另一个字符串中的第一次出现,则该函数返回第一次匹配的字符串的地址,找不到返回NULL)
                     判断参数1中的字符在参数2的字符串char*中出现的索引
                     [obj objCType] 如果obj是int返回字符串i
                     */
                    if (strstr("ilsILS", [obj objCType])) {
                        /*
                         绑定参数 如果有where
                         参数1:sqlite_stmt对象 (statement结果集)
                         参数2:占位符索引 从1开始
                         参数3:替代占位符的真实参数
                         */
                        sqlite3_bind_int(stmt, i+1, [obj intValue]);
                    }
                    else if (strstr("fdFD", [obj objCType]))
                    {
                        sqlite3_bind_double(stmt, i+1, [obj doubleValue]);
                    }
                    else
                    {
                        stmt = nil;
                    }
                }
                else if ([obj respondsToSelector:@selector(UTF8String)])
                {
                    //当前的绑定的数据类型位NSString 判断是否有UTF8String方法
                    //用bind替换占位符 索引从1开始
                    sqlite3_bind_text(stmt, i+1, [obj UTF8String], -1, NULL);
                }
                else
                {
                    stmt = nil;
                }
            }

            return stmt;
        }
    }

    return NULL;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end

  疑问咨询或技术交流,请加入官方QQ群: (452379712)

作者:杰瑞教育

出处:http://blog.csdn.net/jerehedu/

本文版权归烟台杰瑞教育科技有限公司和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

时间: 2024-10-30 14:09:29

IOS 数据存储之 SQLite详解的相关文章

IOS 数据存储之 FMDB 详解

FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语言API,使用起来更加的方便,不需要过多的关心数据库操作的知识.但是它本身也存在一些问题,比如跨平台,因为它是用oc的语言封装的,所以只能在ios开发的时候使用,如果想实现跨平台的操作,来降低开发的成本和维护的成本,就需要使用比较原始的SQLite. Core Data是ORM的一种体现,使用Core Data需要用到模型数据的转化,虽

Android开发数据存储之ContentProvider详解

转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据进行添删改查.关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE或Context.MODE_W

IOS数据存储之Sqlite数据库

前言: 之前学习了数据存储的NSUserDefaults,归档和解档,沙盒文件存储,但是对于数据量比较大,需要频繁查询,删除,更新等操作的时候无论从效率上还是性能上,上述三种明显不能满足我们的日常开发需要了.这个时候我们必须借助数据库,做为Android开发的都知道采用的是一种轻量级数据库Sqlite.其实它广泛用于包括浏览器.IOS,Android以及一些便携需求的小型web应用系统.它具备占用资源低,处理速度快等优点.接下来我们具体认识一下. 我们在项目开发中需要引入libsqlite3.d

安卓数据存储总结及详解

前言(首先说说什么存储的几个概念) 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的时候又是清除的哪里的数据? 在Android开发中我们常常听到这样几个概念,内存,内部存储,外部存储,很多人常常将这三个东西搞混,那么我们今天就先来详细说说这三个东西是怎么回事? 内存: 我们在英文中称作memory,内部存储,我们称为InternalStorage,外部存储我们称为Exte

Android基础之十四数据存储 之 SQLite数据库详解

Android基础之十四数据存储 之 SQLite数据库详解 SQLite 是一款 轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 K 的内存就足够了,因而特别适合在移动设备上使用. SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID( 原子性(Atomicity) .一致性(Consistency) . 隔离性(Isolation) . 持久性(Durability))事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手 SQLite.而

iOS SQLite详解

这周比较忙,前几天都加班到11点左右,基本都是到家都是12点左右(稍稍的抱怨一下,免费加班,何为免费,就是任何补偿都没有,例如调休,加班薪,餐补等各项福利,是一点都没有呀)因为App要上线了!App上线,也可以抽出部分时间整理自己的东西啦,准备花一周时间讲述iOS数据存储方式.本篇主要是讲SQLite的使用和封装,读完大约10-15分钟. 一.SQLite概念 SQLite是轻量型关系型数据库(下面将拓展关系型数据库的概念):占用资源非常少:是无类型的数据库(意思是可以保存所有类型的数据)---

iOS网络编程(六) NSURLSession详解

昨夜浏览Demo的时候,看到别人请求网络数据用的是NSURLSession,当时就在想这里什么,怎么没有用过,引起了我的好奇心,遂去百度-谷歌-官方文档一一查看,有了一定的了解,原来NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的. 查找资料,写了一个小Demo,大家可以看看,有什么不足的地方,可以留言帮我指出来. // // HMTRootViewController.m // // // Created by HMT on 14-6-7.

IOS数据存储 —— 2 存储方式

IOS数据存储方式 iOS开发常用数据存储方式有:plist.偏好设置 NSUserDefaults.对象归档 NSKeyedArchiver.SQLite3和Core Data 1. plist文件 存储 plist文件通常用于储存用户设置,利用xml属性列表归档NSDictionary.NSArray.NSNumber等类型数据 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用 注意:plist不能存储自定义对象 2. 偏好设置 NSUserDefaults 偏好设置

解析activity之间数据传递方法的详解

转自:http://www.jb51.net/article/37227.htm 本篇文章是对activity之间数据传递的方法进行了详细的分析介绍,需要的朋友参考下 1  基于消息的通信机制 Intent--------boudle,extra用这种简单的形式,一般而言传递一些简单的类型是比较容易的,如int.string等详细介绍下Intent机制Intent包含两部分:1 目的[action]-------要去到哪里去2 内容[category.data]----------路上带些什么,