iOS 开发指南 第11章 数据持久化之SQLite 学习

1 SQLite是无数据类型的数据库,就是字段不用指定类型。但从编程规范上说,应该在Create Table语句中指定数据类型:INTERGER 有符号的整数类型 REAL 浮点类型 TEXT 字符串类型 BLOB二进制类型

2 创建数据库:

准备:添加SQLite3库到工程中 TARGETS-Link Binary With Libraries-添加libsqlite3.dylib

使用sqlite3_open打开数据库-使用sqlite3_exec执行Creat Table语句,创建数据库-使用sqlite3_close释放资源

- (void)createEditableCopyOfDatabaseIfNeeded {

    NSString *writableDBPath = [self applicationDocumentsDirectoryFile];
    const char* cpath = [writableDBPath UTF8String];将路径转变为C字符串

    if (sqlite3_open(cpath, &db) != SQLITE_OK) { sqlite3 *db;db是数据库指针
        sqlite3_close(db);
        NSAssert(NO,@"数据库打开失败。");
    } else {
        char *err;        构建SQL语句
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Note (cdate TEXT PRIMARY KEY, content TEXT);"];
        const char* cSql = [sql UTF8String];
        执行参数分别是 sqlite3指针变量 要执行的SQL语句 要回调的函数 要回调函数的参数 执行出错的字符串
        if (sqlite3_exec(db, cSql,NULL,NULL,&err) != SQLITE_OK) {顺序是 先执行在判断
            sqlite3_close(db);
            NSAssert(NO, @"建表失败");
        }
        sqlite3_close(db);
    }
}

**********

NSAssert()只是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续运行,如果返回假值,则抛出异常,并切可以自定义异常描述。NSAssert()是这样定义的:

#define NSAssert(condition, desc)

condition是条件表达式,值为YES或NO;desc为异常描述,通常为NSString。当conditon为YES时程序继续运行,为NO时,则抛出带有desc描述的异常信息。NSAssert()可以出现在程序的任何一个位置。

**********

3 查询数据

查询条件使用where语句,在程序中需要动态绑定参数给where语句

使用sqlite3_open打开数据库-使用sqlite3_prepare_v2预处理SQL语句-使用sqlite3_bind_text绑定参数-使用sqlite3_step执行SQL语句,遍历结果集-使用sqlite3_column_text提取字段数据-使用sqlite3_finalize和sqlite3_close释放资源

//按照主键查询数据方法
-(Note*) findById:(Note*)model
{

    NSString *path = [self applicationDocumentsDirectoryFile];
    const char* cpath = [path UTF8String];

    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO,@"数据库打开失败。");
    } else {

        NSString *sql = @"SELECT cdate,content FROM Note where cdate =?";?代表动态参数
        const char* cSql = [sql UTF8String];

        sqlite3_stmt *statement;
        //预处理过程 目的是将SQL语句编译成二进制代码,提高SQL语句的执行速度。          第三个参数开始 代表全部的SQL字符串长度 语句对象:通过语句对象可以执行SQL语句 SQL语句没有执行的那部分if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            //准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char* cDate  = [strDate UTF8String];
            //绑定参数开始             参数:指针 序号:从1开始 字符串(参数) 字符串长度 函数指针            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            //执行
            if (sqlite3_step(statement) == SQLITE_ROW) {若函数返回值等于SQLITE_ROW,表示还有其他的行没有遍历

                char *bufDate = (char *) sqlite3_column_text(statement, 0);第二个参数用于指定select字段的索引
                NSString *strDate = [[NSString alloc] initWithUTF8String: bufDate];
                NSDate *date = [dateFormatter dateFromString:strDate];

                char *bufContent = (char *) sqlite3_column_text(statement, 1);
                NSString * strContent = [[NSString alloc] initWithUTF8String: bufContent];

                Note* note = [[Note alloc] initWithDate:date content:strContent];

                sqlite3_finalize(statement);
                sqlite3_close(db);

                return note;
            }
        }

        sqlite3_finalize(statement);
        sqlite3_close(db);

    }
    return nil;
}

4 修改数据

涉及的SQL语句有insert update delete

使用sqlite3_open打开数据库-使用sqlite3_prepare_v2预处理SQL语句-使用sqlite3_bind_text绑定参数-使用sqlite3_step执行SQL语句-使用sqlite3_finalize和sqlite3_close关闭数据库

//插入Note方法
-(int) create:(Note*)model
{

    NSString *path = [self applicationDocumentsDirectoryFile];
    const char* cpath = [path UTF8String];

    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO,@"数据库打开失败。");
    } else {

        NSString *sql = @"INSERT OR REPLACE INTO note (cdate, content) VALUES (?,?)";
        const char* cSql = [sql UTF8String];

        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {

            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char* cDate  = [strDate UTF8String];

            const char* cContent = [model.content UTF8String];

            //绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            sqlite3_bind_text(statement, 2, cContent, -1, NULL);

            //执行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"插入数据失败。");
            }
        }

        sqlite3_finalize(statement);
        sqlite3_close(db);
    }

    return 0;
}

//删除Note方法
-(int) remove:(Note*)model
{
    NSString *path = [self applicationDocumentsDirectoryFile];
    const char* cpath = [path UTF8String];    

    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO,@"数据库打开失败。");
    } else {
        NSString *sql = @"DELETE  from note where cdate =?";
        const char* cSql = [sql UTF8String];

        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char* cDate  = [strDate UTF8String];

            //绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            //执行
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"删除数据失败。");
            }
        }

        sqlite3_finalize(statement);
        sqlite3_close(db);
    }

    return 0;
}

//修改Note方法
-(int) modify:(Note*)model
{

    NSString *path = [self applicationDocumentsDirectoryFile];
    const char* cpath = [path UTF8String];

    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO,@"数据库打开失败。");
    } else {

        NSString *sql = @"UPDATE note set content=? where cdate =?";
        const char* cSql = [sql UTF8String];

        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {

            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char* cDate  = [strDate UTF8String];

            const char* cContent = [model.content UTF8String];

            //绑定参数开始
            sqlite3_bind_text(statement, 1, cContent, -1, NULL);
            sqlite3_bind_text(statement, 2, cDate, -1, NULL);
            //执行
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"修改数据失败。");
            }
        }

        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
    return 0;
}
时间: 2024-11-09 13:33:16

iOS 开发指南 第11章 数据持久化之SQLite 学习的相关文章

iOS 开发指南 第11章 数据持久化之属性列表 学习

1 概述 沙箱目录:一种安全策略,原理是只能允许自己的应用访问目录,而不许其他应用访问. 子目录:Documents 用于储存非常大的文件或需要非常频繁更新的数据 NSArray *documentDirectory=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES): documentDirectory是只有一个元素的数组,还需要取出路径 NSString *myDocPath=[docum

iOS 开发指南 第11章 数据持久化之对象归档 学习

1 是一种序列化方式,先将归档对象序列化为一个文件,然后再通过反归档将数据恢复到对象中. 条件:该对象的类必须实现NSCoding协议,而且每个成员变量应该是基本数据类型或都是实现NSCoding协议的某个类的实例. 归档类NSKeyedArchiver 反归档类NSKeyedUnarchiver  NSData类提供了读取数据文件的方法 方法:+dataWithContentsOfFile: +dataWithContentsOfFile:options:指定读取数据选项error: -ini

IOS开发指南第四章 IOS8多分辨率屏幕适配 学习

1 获取IOS设备屏幕信息 CGSize iOSDeviceScreenSize = [UIScreen mainScreen].bounds.size; NSString *s = [NSString stringWithFormat:@"%.0f x %.0f", iOSDeviceScreenSize.width, iOSDeviceScreenSize.height]; 获取设备信息判断是否是ipone-判断横屏还是竖屏-判断设备型号 属性userInterfaceIdiom是

ios开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

               在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文本框内容的创建.修改,退出后台,再重新回到后台,来认识这两种持久化数据的方式.效果图如下[图1]: [图1 GUI界面效果图] [本次开发环境: Xcode:7.2     iOS Simulator:iphone6S plus   By:啊左]     一.数据库SQL

iOS 开发指南 第15章 访问Web Service之数据交换格式

“自描述的”结构化文档 1 XML文档结构 声明:定义了XML文件的版本和使用的字符集 <> 根元素:开始标签  结束标签 子元素:开始标签 结束标签 属性:  定义在开始标签中 属性名 属性值(放置在双引号或单引号之间) 一个元素不能有多个名字相同的属性. 命名空间:为XML文档提供名字唯一的元素和属性 ************ XML 命名空间提供避免元素命名冲突的方法. XML Namespace (xmlns) 属性 XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法:

iOS开发指南 第8章 iOS常用设计模式 学习

设计模式是在特定场景下对特定问题的解决方案 1 单例模式 作用:解决“应用中只有一个实例”的问题,这个实例的作用是全局的,比如说是可以实现一些共享资源 方法的访问和状态的保持 实现原理:一般会封装一个静态属性,并提供静态实例的创建方法. *********** James Rumbaugh对类的定义是:类是具有相似结构.行为和关系的一组对象的描述符.类是面向对象系统中最重要的构造块.类图显示了一组类.接口.协作以及他们之间的关系. 建立类图的步骤: (1)研究分析问题领域确定系统需求. (2)确

IOS 开发指南 第三章学习

1 uiwindow 的rootwiew决定了应用程序的类型 2 反映视图关系的3个属性 superview:有且仅有一个(除了uiwindow) subviews:子视图的集合 window:获得当前视图的uiwindow对象 3 按钮至少有两种:uibutton uibarbuttonitem 4 selector是一个指针变量,意思是将方法指定给控件去做 sender是事件源,指要使用这个方法的控件对象 5 使控件的事件与动作关联在一起 1)addTarget:action:forCont

iOS 开发指南 第15章 访问Web Service之REST Web Service

***** 在电脑术语中,统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串. 该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作.URI由包括确定语法和相关协议的方案所定义. Web上可用的每种资源 -HTML文档.图像.视频片段.程序等 - 由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位. ***** 1 REST Web Ser

IOS 开发指南 第5章 委托协议 数据源协议 高级视图学习

1 委托对象负责控制控件的外观和对控件的事件和状态作出反应 数据源对象是控件与应用数据(model)的桥梁,一般是必须实现的. 2 选择器 UIPickerView 为用户提供选择 1)日期选择器 UIDatePicker 设置属性检查器中的各个属性-代码 -setDateFormat:设置日期格式 -stringFromDate:获取时间 - (IBAction)onclick:(id)sender { NSDate * theDate = self.datePicker.date;获取选中日