IOS-SQLite数据库使用详解

使用SQLite数据库

创建数据库

创建数据库过程需要3个步骤:

1、使用sqlite3_open函数打开数据库;

2、使用sqlite3_exec函数执行Create Table语句,创建数据库表;

3、使用sqlite3_close函数释放资源。

这个过程中使用了3个SQLite3函数,它们都是纯C语言函数,通过Objective-C去调用C函数当然不是什么问题,但是也要注意Objective-C数据类型与C数据类型兼容性问题。

下 面我们使用SQLite技术实现备忘录案例,与属性列表文件实现一样,我们只需要修改持久层工程(PersistenceLayer)中NoteDAO类 就可以了。首先我们需要添加SQLite3库到工程环境中,有3个工程需要添加到哪个呢?应该添加到可以运行的工程即表示层工程 PresentationLayer。选择工程PresentationLayer中 TARGETS→PresentationLayer→Link Binary With Libraries,点击左下角的“+”,弹出对话框选择 libsqlite3.dylib或libsqlite3.0.dylib,在弹出的对话框中点击Add添加。

NoteDAO.h文件的修改:

Cpp代码  

  1. #import ”Note.h”
  2. #import ”sqlite3.h”
  3. #define DBFILE_NAME @”NotesList.sqlite3″
  4. @interface NoteDAO : NSObject
  5. {
  6. sqlite3 *db;
  7. }
  8. + (NoteDAO*)sharedManager;
  9. - (NSString *)applicationDocumentsDirectoryFile;
  10. - (void)createEditableCopyOfDatabaseIfNeeded;
  11. //插入Note方法
  12. -(int) create:(Note*)model;
  13. //删除Note方法
  14. -(int) remove:(Note*)model;
  15. //修改Note方法
  16. -(int) modify:(Note*)model;
  17. //查询所有数据方法
  18. -(NSMutableArray*) findAll;
  19. //按照主键查询数据方法
  20. -(Note*) findById:(Note*)model;
  21. @end

我们需要使用语句#import ”sqlite3.h”引入sqlite3头文件,而且需要定义sqlite3*成员变量db。NoteDAO.m中的createEditableCopyOfDatabaseIfNeeded方法:

Cpp代码  

  1. - (void)createEditableCopyOfDatabaseIfNeeded {
  2. NSString *writableDBPath = [self applicationDocumentsDirectoryFile];
  3. if (sqlite3_open([writableDBPath UTF8String], &db) != SQLITE_OK) { ①
  4. sqlite3_close(db);  ②
  5. NSAssert(NO,@”数据库打开失败。”);
  6. } else {
  7. char *err;
  8. NSString *createSQL = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Note
  9. (cdate TEXT PRIMARY KEY, content TEXT);"]; ③
  10. if (sqlite3_exec(db,[createSQL UTF8String],NULL,NULL,&err) != SQLITE_OK) { ④
  11. sqlite3_close(db); ⑤
  12. NSAssert1(NO, @”建表失败, %s”, err);  ⑥
  13. }
  14. sqlite3_close(db);  ⑦
  15. }
  16. }

createEditableCopyOfDatabaseIfNeeded方法用于创建数据库,第1步打开数据 库,代码①行,语句是 sqlite3_open([writableDBPath UTF8String], &db),sqlite3_open函数的第1个参数是 数据库文件完整的路径,但是需要注意的是在SQLite3函数中接受的是char*的UTF-8类型数据,需要将NSString*转换为UTF-8,使 用NSString*的UTF8String方法可以转换,sqlite3_open函数第2个参数sqlite3指针变量db的地址。该函数的返回值是 int类型,在SQLite3中定义了很多常量,返回值等于常量SQLITE_OK则说明操作成功。

第2步执行建表语句,代码第④行,语句 sqlite3_exec(db,[createSQL UTF8String],NULL,NULL,&err)执行建表的SQL。第1个参数 是sqlite3指针变量db的地址,第2个参数是要执行的sql语句,第3个参数是要回调函数,第4个参数是要回调函数的参数,第5个参数是执行出错的 字符串。建表SQL语句是,如果表Note存在这不用创建。

CREATE TABLE IF NOT EXISTS Note (cdate TEXT PRIMARY KEY, content TEXT)

第3步使用sqlite3_close函数释放资源,代码②、⑤、⑦行所示,在数据库打开失败、Create Table执行失败和成功执行完成时候调用。原则上无论正常结束还是异常结束必须使用sqlite3_close函数释放资源。

查询数据

数据查询一般会带有查询条件,这个使用SQL语句where子句很容易实现,但是在程序中需要动态绑定参数给where子句。执行查询数据步骤如下:

1、使用sqlite3_open函数打开数据库;

2、使用sqlite3_prepare_v2函数预处理SQL语句;

3、使用sqlite3_bind_text函数绑定参数;

4、使用sqlite3_step函数执行SQL语句,遍历结果集;

5、使用sqlite3_column_text等函数提取字段数据;

6、使用sqlite3_finalize和sqlite3_close函数释放资源。

NoteDAO.m中的按照主键查询数据方法:

Cpp代码  

  1. -(Note*) findById:(Note*)model
  2. {
  3. NSString *path = [self applicationDocumentsDirectoryFile];
  4. if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { ①
  5. sqlite3_close(db);  ②
  6. NSAssert(NO,@”数据库打开失败。”);
  7. } else {
  8. NSString *qsql = @”SELECT cdate,content FROM Note where cdate =?”;
  9. sqlite3_stmt *statement;
  10. //预处理过程
  11. if (sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, NULL) == SQLITE_OK) { ③
  12. //准备参数
  13. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; ④
  14. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  15. NSString *nsdate = [dateFormatter stringFromDate:model.date];
  16. //绑定参数开始
  17. sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL); ⑤
  18. //执行
  19. if (sqlite3_step(statement) == SQLITE_ROW) { ⑥
  20. char *cdate = (char *) sqlite3_column_text(statement, 0); ⑦
  21. NSString *nscdate = [[NSString alloc] initWithUTF8String: cdate];
  22. char *content = (char *) sqlite3_column_text(statement, 1);
  23. NSString * nscontent = [[NSString alloc] initWithUTF8String: content];
  24. Note* note = [[Note alloc] init];
  25. note.date = [dateFormatter dateFromString:nscdate];
  26. note.content = nscontent;
  27. sqlite3_finalize(statement);
  28. sqlite3_close(db);
  29. return note;
  30. }
  31. }
  32. sqlite3_finalize(statement); ⑧
  33. sqlite3_close(db);  ⑨
  34. }
  35. return nil;
  36. }

该方法执行了6个步骤,其中第1个步骤,代码第①行所示,它与创建数库的第1个步骤是一样的,不用再介绍了。

第 2个步骤,代码第③行所示,语句 sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, NULL)是预处理 SQL语句,预处理目的是将SQL编译成二进制代码,提高SQL语句执行的速度。sqlite3_prepare_v2函数的第3个参数-1代表全部 sql字符串长度,第4个参数&statement是sqlite3_stmt指针的地址,它是语句对象,通过语句对象可以执行SQL语句,第5 个参数是sql语句没有被执行的部分语句。

第3个步骤,代码第⑤行所示,语句sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL)是绑定SQL语句参数。在SQL语句中带有问号,这个问号就是要绑定的参数,问号是占位符。

NSString *qsql = @”SELECT cdate,content FROM Note where cdate =?”;

sqlite3_bind_text函数是绑定参数,第1个参数是statement指针,第2个参数为序号(从1开始),第3个参数为字符串值,第4个参数为字符串长度,第5个参数为一个函数指针。

第4个步骤sqlite3_step(statement)执行SQL语句,代码第⑥行所示,sqlite3_step返回int类型,等于SQLITE_ROW说明还要其它的行没有遍历。

第 5个步骤提取字段数据,代码第⑦行所示,使用sqlite3_column_text(statement, 0)函数可以读取字符串类型字段,第2参数 是指定select字段的索引(从0开始)。同样char*转换成为NSString*类型,需要initWithUTF8String:构造方法。读取 字段函数采用与字段类型有关系,SQLite3的类似的常用函数还有:

sqlite3_column_blob()

sqlite3_column_double()

sqlite3_column_int()

sqlite3_column_int64()

sqlite3_column_text()

sqlite3_column_text16()

关于其它的API可以参考http://www.sqlite.org/cintro.html。

第6个步骤是释放资源,创建数据库过程不同,除了使用sqlite3_close函数关闭数据库,代码第⑧行所示,还要使用sqlite3_finalize函数释放语句对象statement代码第⑨行所示。

NoteDAO.m中的查询所有数据方法:

Cpp代码  

  1. -(NSMutableArray*) findAll
  2. {
  3. NSString *path = [self applicationDocumentsDirectoryFile];
  4. NSMutableArray *listData = [[NSMutableArray alloc] init];
  5. if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) {
  6. sqlite3_close(db);
  7. NSAssert(NO,@”数据库打开失败。”);
  8. } else {
  9. NSString *qsql = @”SELECT cdate,content FROM Note”;
  10. sqlite3_stmt *statement;
  11. //预处理过程
  12. if (sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, NULL) == SQLITE_OK) {
  13. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  14. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  15. //执行
  16. while (sqlite3_step(statement) == SQLITE_ROW) {
  17. char *cdate = (char *) sqlite3_column_text(statement, 0);
  18. NSString *nscdate = [[NSString alloc] initWithUTF8String: cdate];
  19. char *content = (char *) sqlite3_column_text(statement, 1);
  20. NSString * nscontent = [[NSString alloc] initWithUTF8String: content];
  21. Note* note = [[Note alloc] init];
  22. note.date = [dateFormatter dateFromString:nscdate];
  23. note.content = nscontent;
  24. [listData addObject:note];
  25. }
  26. }
  27. sqlite3_finalize(statement);
  28. sqlite3_close(db);
  29. }
  30. return listData;
  31. }

查询所有数据方法与按照主键查询数据方法类似,区别在于本方法没有查询条件不需要绑定参数。遍历的时候使用while循环语句,不是if语句。

while (sqlite3_step(statement) == SQLITE_ROW) {

… …

}

修改数据 

修改数据包括:insert、update和delete语句。这3个SQL语句都可以带有参数,关于参数的绑定与查询where子句绑定的方式是一样的。执行修改数据步骤如下:

1、使用sqlite3_open函数打开数据库;

2、使用sqlite3_prepare_v2函数预处理SQL语句;

3、使用sqlite3_bind_text函数绑定参数;

4、使用sqlite3_step函数执行SQL语句;

5、使用sqlite3_finalize和sqlite3_close函数释放资源。

修改数据的步骤与查询数据的步骤相比少了一个提取字段数据步骤。下面我们看看代码部分。其它的步骤是一样的。

NoteDAO.m中的插入Note方法:

Cpp代码  

  1. -(int) create:(Note*)model
  2. {
  3. NSString *path = [self applicationDocumentsDirectoryFile];
  4. if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) { ①
  5. sqlite3_close(db);  ②
  6. NSAssert(NO,@”数据库打开失败。”);
  7. } else {
  8. NSString *sqlStr = @”INSERT OR REPLACE INTO note (cdate, content) VALUES (?,?)”;
  9. sqlite3_stmt *statement;
  10. //预处理过程
  11. if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) { ③
  12. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  13. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  14. NSString *nsdate = [dateFormatter stringFromDate:model.date];
  15. //绑定参数开始
  16. sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL);  ④
  17. sqlite3_bind_text(statement, 2, [model.content UTF8String], -1, NULL);
  18. //执行插入
  19. if (sqlite3_step(statement) != SQLITE_DONE) { ⑤
  20. NSAssert(NO, @”插入数据失败。”);
  21. }
  22. }
  23. sqlite3_finalize(statement);  ⑥
  24. sqlite3_close(db);  ⑦
  25. }
  26. return 0;
  27. }

第⑤行代码sqlite3_step(statement)语句执行插入语句,常量SQLITE_DONE执行完成。

NoteDAO.m中的删除Note方法:

Cpp代码  

    1. -(int) remove:(Note*)model
    2. {
    3. NSString *path = [self applicationDocumentsDirectoryFile];
    4. if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) {
    5. sqlite3_close(db);
    6. NSAssert(NO,@”数据库打开失败。”);
    7. } else {
    8. NSString *sqlStr = @”DELETE  from note where cdate =?”;
    9. sqlite3_stmt *statement;
    10. //预处理过程
    11. if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) {
    12. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    13. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    14. NSString *nsdate = [dateFormatter stringFromDate:model.date];
    15. //绑定参数开始
    16. sqlite3_bind_text(statement, 1, [nsdate UTF8String], -1, NULL);
    17. //执行插入
    18. if (sqlite3_step(statement) != SQLITE_DONE) {
    19. NSAssert(NO, @”删除数据失败。”);
    20. }
    21. }
    22. sqlite3_finalize(statement);
    23. sqlite3_close(db);
    24. }
    25. return 0;
    26. }
    27. NoteDAO.m中的修改Note方法:
    28. -(int) modify:(Note*)model
    29. {
    30. NSString *path = [self applicationDocumentsDirectoryFile];
    31. if (sqlite3_open([path UTF8String], &db) != SQLITE_OK) {
    32. sqlite3_close(db);
    33. NSAssert(NO,@”数据库打开失败。”);
    34. } else {
    35. NSString *sqlStr = @”UPDATE note set content=? where cdate =?”;
    36. sqlite3_stmt *statement;
    37. //预处理过程
    38. if (sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &statement, NULL) == SQLITE_OK) {
    39. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    40. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    41. NSString *nsdate = [dateFormatter stringFromDate:model.date];
    42. //绑定参数开始
    43. sqlite3_bind_text(statement, 1, [model.content UTF8String], -1, NULL);
    44. sqlite3_bind_text(statement, 2, [nsdate UTF8String], -1, NULL);
    45. //执行插入
    46. if (sqlite3_step(statement) != SQLITE_DONE) {
    47. NSAssert(NO, @”修改数据失败。”);
    48. }
    49. }
    50. sqlite3_finalize(statement);
    51. sqlite3_close(db);
    52. }
    53. return 0;
    54. }
时间: 2024-10-12 22:46:59

IOS-SQLite数据库使用详解的相关文章

windows phone 8.1开发SQlite数据库操作详解

原文出自:http://www.bcmeng.com/windows-phone-sqlite1/ 本文小梦将和大家分享WP8.1中SQlite数据库的基本操作:(最后有整个示例的源码)(希望能通过本站广告支持小梦,谢谢!) 建立数据库 增加数据 删除数据 更改数据 查询数据 (注:为了让每个操作都能及时显示在UI上,所以进行了数据绑定.数据绑定会在后面文章专门讲解,先给出数据类Note,代表一个笔记.含有Name 和content  属性.其代码如下:如果不清楚,我会在之后讲解): names

IOS 友盟使用详解

IOS 友盟使用详解 这篇博客将会详细介绍友盟的使用,希望对博友们有所帮助. 首先我们在浏览器上搜索友盟. 在这里我们选择官网这个,进去友盟官网后我们按照下图进行选择. 接下来选择如下图 Next 这样我们便进入到了帮助文档 如果还没有友盟账号那么我们就需要注册一下了(点击图片中的注册即可) 注册成功并且登陆后我们需要按照操作获取Appkey 操作如图 NEXT 成功获取Appkey(复制下来,接下来会用到) 返回帮助文档 接下来是下载(安装)SDK,我么可以按照图片中的两种方法操作. 我选择了

ios新特征 ARC详解

IOS ARC 分类: IOS ARC2013-01-17 09:16 2069人阅读 评论(0) 收藏 举报 目录(?)[+] 关闭工程的ARC(Automatic Reference Counting) 顺带附上ARC教程 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论.请不要将本文的部分或全部内容用于商用,谢谢合作. 欢迎转载本文,但是转载请注明本文出处:http://www.onevcat.com/2012/06/arc-hand-by

Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']

public function getMinLimit () {        $sql = "...";        $result = yii::app()->db->createCommand($sql);        $query = $result->queryAll();         return array (                $query [0] ['max'],         );    } $connection=Yii::

iOS定位服务编程详解

现在的移动设备很多都提供定位服务,使用iOS系统的iPhone.iPod Touch和iPad都可以提供位置服务,iOS设备能提供3种不同途径进行定位:Wifi, 蜂窝式移动电话基站, GPS卫星 iOS 不像Android系统在定位服务编程时,可以指定采用哪种途径进行定位.iOS的API把底层这些细节屏蔽掉了,开发人员和用户并不知道现在设备是采用 哪种方式进行定位的,iOS系统会根据设备的情况和周围的环境,采用一套最佳的解决方案.这个方案是这样的,如果能够接收GPS信息,那么设备优先采用 GP

iOS学习--UIScrollView 原理详解

iOS学习--UIScrollView 原理详解 http://blog.csdn.net/yanfangjin/article/details/7898189 ScrollView UIScrollView UIScrollView为了显示多于一个屏幕的内容或者超过你能放在内存中的内容. Scroll View为你处理缩小放大手势,UIScrollView实现了这些手势,并且替你处理对于它们的探测和回应.其中需要注意的子类是UITableView以及UITextView(用来显示大量的文字).

H2数据库使用 详解

H2最完整的资料下载地址: http://download.csdn.net/detail/yixiaoping/5956595 H2数据库使用 H2数据库介绍 常用的开源数据库:H2,Derby,HSQLDB,MySQL,PostgreSQL.其中H2,HSQLDB类似,十分适合作为嵌入式数据库使用,其它的数据库大部分都需要安装独立的客户端和服务器端.H2的优势:1.h2采用纯Java编写,因此不受平台的限制.2.h2只有一个jar文件,十分适合作为嵌入式数据库试用.3.性能和功能的优势 H2

如何查看mysql数据库的引擎/MySQL数据库引擎详解

一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mysql> show variables like '%storage_engine%'; 你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):mysql> show create table 表名; MySQL数据库引擎详解 作为Java程序员,MySQL数据库

(转) IOS ASI http 框架详解

(转) IOS ASI http 框架详解 ASIHTTPRequest对CFNetwork API进行了封装,并且使用起来非常简单,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中.ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互. ASIHTTPRequest功能很强大,主要特色如下: l 通过简单的接口,即可完成向服务端提交数据和从服务端获取数据的工作 l 下载的数据,可存储到内存中或直接存储到磁盘中 l 能上传

MySQL数据库优化详解(收藏)

MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * from t1;mysql索引 ALTER TABLE用来创建普通索引.UNIQUE索引或PRIMARY KEY索引ALTER TABLE table_name ADD INDEX index_name (column_list)ALTER TABLE table_name ADD UNIQUE (colu