`

iPhone实战:操作SQLite(转)

 
阅读更多

SQLite是一款轻量级的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,当然还有我们使用的Obj-C。用这种方法保存的数据既可以在客户端存储大量数据,同时能够利用SQL语句灵活地查询、插入、更新或者删除数据。 本人在开发过程中发现关于iOS中SQLite的编程文章实在太少了,大多数都是涉及都一些简单的操作。因此,下面写到的操作我会在简单的SQLite操作基础上(其中包括打开/关闭数据库、构造表、插入、更新或者删除数据操作),再增加两项数据库操作中比较常用的功能实践,分别实现带参数SQL语句的执行以及数据库的事物启动、提交和回滚。废话不多说,直接进入主题吧。 在iOS中使用SQLite我们需要加入libsqlite3.dylib的库,并在引入SQLite的头文件。如下: #import <sqlite3.h> 导入库和头文件之后,接下来的操作就是打开一个数据库。这时候需要调用sqlite3_open这个函数来对打开一个数据库文件。此函数声明如下: int sqlite3_open( const char*filename, /* Database filename (UTF-8)*/ sqlite3 **ppDb /* OUT: SQLite db handle */ ); 其中第一个参数就是数据库所存放的路径,如果路径下没有数据库文件则系统会在此路径下创建一个数据库。至于第二个参数则是数据库的句柄引用,但此函数调用成功后此句柄将会保存打开数据库的句柄,此句柄在往后的数据库操作中需要用到。因此,可如下方式调用: NSString*dbPath=[NSString stringWithFormat:@”%@/Documents/demo.db”,NSHomeDirectory()]; sqlite3*dbHandle; if (sqlite3_open([pathUTF8String], &amp;dbHandle)==SQLITE_OK) { NSLog(@“打开数据库成功!”); } 既然有打开数据库,那么就肯定有关闭数据库的操作了,我们要养成良好的习惯,当需要使用数据库的时候就执行sqlite3_open来打开数据库,等使用完数据库后就调用sqlite3_close函数来对数据库进行关闭。关于sqlite3_close函数声明如下: int sqlite3_close(sqlite3 *); 关闭时传入数据库句柄即可对数据库进行关闭。调用方式如下: if(sqlite3_close(dbHandle)==SQLITE_OK) NSLog(@“关闭数据库成功!”); 接下来需要讲述的是如何对数据库进行操作,常用的有两种方式可以操作数据库中的数据和调整结构。 第一种就是sqlite3_exec函数,这种方法一般使用在不返回数据集的情况,也就是说少用于查询类的操作,同时笔者也尚发现使用此函数如何配合参数使用。如果使用他来创建表结构、更新、插入或者删除操作是一种直观快捷的方法。先来看看此方法的声明: intsqlite3_exec( sqlite3*, /* An opendatabase */ const char *sql, /* SQL to beevaluated */ int(*callback)(void*,int,char**,char**), /*Callback function */ void *, /* 1stargument to callback */ char **errmsg /* Error msgwritten here */ ); 第一个参数就是我们打开数据库的句柄了,第二个参数就是SQL语句,第三个参数为回调方法的函数指针,一旦指定此参数后,当执行语句为查询语句时则在枚举记录集时回对调此方法。第四个参数则为回调的第一个参数引用。关于第三第四个参数还有待研究(如果哪位大虾知道如何使用,不妨告诉小弟,一定感激不尽)。至于第五个参数就是如果方法执行后存在异常,那么这个参数保存的就是错误的描述信息。 第二种就是使用sqlite3_prepare_v2和sqlite3_step两个函数搭配的进行操作。其中sqlite3_prepare_v2是一个将SQL语句编译为sqlite内部一个结构体(sqlite3_stmt).该结构体中包含了将要执行的的SQL语句的信息。而sqlite3_step则是让转化后的SQL进行下一步的操作。因此通过这两个函数可以很方便的获取到数据库中的数据。本人建议使用此方式取得记录集。下面是这两个函数的声明: int sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char*zSql, /* SQL statement, UTF-8encoded */ int nByte, /* Maximum length of zSql inbytes. */ sqlite3_stmt**ppStmt, /* OUT: Statement handle */ const char**pzTail /* OUT: Pointer to unusedportion of zSql */ ); 第一个参数就是打开数据库时的数据库句柄对象。第二个就是SQL语句。第三个参数是用于指定SQL语句最大的长度,如果此参数为负数,则根据第二个参数中的第一个终结符为准作为一条完整的语句。如果为非负数,则以第二个参数的第一个终结符(\000或\u0000)或者指定的数字为准作为一条完整语句。第四个参数则是调用函数后返回的一个结构体,此结构体包含了相关语句的信息。关于第五个参数是用于指向前一条语句结束位置,一旦指定此参数,则参数指向位置的左边语句将不进行编译解析。 sqlite3_step(sqlite3_stmt*); 传入参数即为准备语句中的结构体对象。 上面所说的两种方式我将会在下面举例进行说明,但是每个例子不一定两种方式都实现,如果有这方面兴趣的朋友可以自己尝试另外一种方式实现。 例子一:创建数据表 要想让数据库能够存储数据,那就必须得创建一个数据表才能进行数据操作。而数据表是可以包含不同的数据字段,这些字段可以指定不同的数据类型,存储不同的数据。我们建表时可以根据需要进行创建。下面的代码创建了一个叫做persons的数据表,其包含两个字段id和name。其SQL语句为:create table if not exists persons (id integerprimary key autoincrement,name);(如果对SQL语句不太熟悉的朋友可以参考相关方面资料)。那么代码如下所示: char *errorMsg; if (sqlite3_exec(_database, "createtable if not exists persons (id integer primary key autoincrement,name);",NULL, NULL, &amp;errorMsg)!=SQLITE_OK) { NSLog(@“操作失败!”); } sqlite3_free(errorMsg); 上面要注意的一点是,如果你有传入errorMsg参数,那么你必须在执行完sqlite3_exec后,执行sqlite3_free函数来释放errorMsg。否则就会造成内存泄露。 例子二:插入、更新、删除数据 上面的例子创建了一个数据后,那么我们可以往里面插入数据,我们可以使用insert语句将数据插入表中:代码如下所示: char *errorMsg; if (sqlite3_exec(_database, "insertinto persons(name) values(‘张三’);",NULL, NULL, &amp;errorMsg)!=SQLITE_OK) { NSLog(@“操作失败!”); } sqlite3_free(errorMsg); 上面所做的事情就是把一个张三的数据插入了数据表persons中。上面的实现是非常方便的,但是并不安全,因为我们的SQL语句中要插入的数据是拼合到SQL语句中的,这样很容易造成注入问题,因此,我们可以使用下面的方法来实现。 sqlite3_stmt *statement; if (sqlite3_prepare_v2(_database, [@"insertinto persons(name) values(?);" UTF8String], -1, &amp;statement,NULL)!=SQLITE_OK) { return; } //绑定参数 const char *text=[@”张三” cStringUsingEncoding:NSUTF8StringEncoding]; sqlite3_bind_text(statement, index, text,strlen(text), SQLITE_STATIC); if (sqlite3_step(statement)!=SQLITE_DONE){ sqlite3_finalize(statement); return; } sqlite3_finalize(statement); 推荐使用参数进行数据查询和操作,这样可以保证读写数据的正确性和提高安全性。对于更新数据和删除数据的调用方式和插入数据一样,只是SQL语句的差异,其中更新数据使用Update语法,而删除表数据则使用Delete语法。 例子三:事务处理 事务在数据库中是一个重要的概念,使用事务可以保证数据的统一和完整性。同时也可以提高效率。拿我们上面创建的persons表来说,假设我要一次插入20个人的名字才算是操作成功,那么,在不使用事务的情况下,如果插入过程中出现异常或者在插入过程中出现一些其他数据库操作的话,就很有可能影响了操作的完整性。所以事务可以很好地解决这样的情况,首先事务是可以把启动事务过程中的所有操作视为事务的过程。等到所有过程执行完毕后,我们可以根据操作是否成功来决定事务是否进行提交或者回滚。提交事务后会一次性把所有数据提交到数据库,如果回滚了事务就会放弃这次的操作,而对原来表的数据不进行更改。 那么,如何启动,提交还有回滚事务呢?SQLite中分别是:BEGIN、COMMIT和ROLLBACK。下面来看一下例子: @try{ char *errorMsg; if(sqlite3_exec(_database, "BEGIN", NULL, NULL, &amp;errorMsg)==SQLITE_OK){ NSLog(@”启动事务成功”); sqlite3_free(errorMsg); sqlite3_stmt*statement; if(sqlite3_prepare_v2(_database, [@"insert into persons(name) values(?);"UTF8String], -1, &amp;statement, NULL)==SQLITE_OK) { //绑定参数 constchar *text=[@”张三”cStringUsingEncoding:NSUTF8StringEncoding]; sqlite3_bind_text(statement,index, text, strlen(text), SQLITE_STATIC); if(sqlite3_step(statement)!=SQLITE_DONE) { sqlite3_finalize(statement); } } if (sqlite3_exec(_database,"COMMIT", NULL, NULL, &amp;errorMsg)==SQLITE_OK) { NSLog(@”提交事务成功”); } sqlite3_free(errorMsg); }else{ sqlite3_free(errorMsg); } } @catch(NSException *e){ char *errorMsg; if(sqlite3_exec(_database, "ROLLBACK", NULL, NULL, &amp;errorMsg)==SQLITE_OK){ NSLog(@”回滚事务成功”); } sqlite3_free(errorMsg); } @finally{ } 关于SQLite的操作今天就到这里告一段落,日后有相关的资料或者经验再跟大家分享。</sqlite3.h>

分享到:
评论

相关推荐

    (英文)Head First Iphone Development: A Learner's Guide to Creating Objective-C Applications for the Iphone 2009

    2. **注重实践操作**:本书强调理论与实践相结合,通过一系列具体的项目案例来引导读者进行实战演练,从而更好地理解和吸收知识。 3. **面向已有编程经验的学习者**:虽然本书定位为入门教材,但它更适合已经有...

    iPhone开发实战上部

    《iPhone开发实战上部》这本书全面且深入地探讨了iOS应用开发的相关知识,特别是针对iPhone和iPad设备。作为一本实战指南,它旨在帮助开发者从零基础开始,逐步掌握iOS平台的开发技能。以下是对书中主要知识点的详细...

    《iPhone App开发实战手册》中文高清版

    《iPhone App开发实战手册》是一本专为iOS开发者编写的指南,主要涵盖了iPhone和iPad应用的开发技术。这本书以中文高清版的形式呈现,适合初学者和有一定经验的开发者,提供了全面且深入的知识讲解。 在iOS开发领域...

    sqlite 数据库

    SQLite是一个轻量级的、开源的、自包含的数据库引擎,广泛应用于移动设备开发,如iPhone,因为它无需服务器进程,可以直接在本地存储和管理数据。SQLite数据库被设计为嵌入式使用,它允许应用程序直接与数据库进行...

    iphone开发实战下部

    总的来说,《iPhone开发实战下部》全面覆盖了iOS开发的核心知识,通过丰富的实例和详细的操作步骤,帮助读者一步步掌握iOS开发技能,无论是想开发个人应用还是参与大型项目,都能从中找到实用的指导。通过阅读本书,...

    iPhone与iPad开发实战(iPhone and iPad in Action )

    ### iPhone与iPad开发实战知识点概览 #### 一、Objective-C基础 - **语言特性**:Objective-C是一种面向对象的编程语言,它扩展了标准的C语言,为开发者提供了更强大的面向对象编程能力。 - **类与对象**:...

    iphone开发实战 书本源码

    在本资源中,“iPhone开发实战 书本源码”提供了从第1章到第20章的完整学习路径,旨在帮助开发者深入理解iOS应用开发。这个压缩包包含了一系列与iOS开发相关的Objective-C代码,适用于那些想要提升iOS编程技能或者...

    iphone应用程序开发入门与实战源码

    《iPhone应用程序开发入门与实战源码》是一本旨在引导初学者进入iOS开发领域的书籍,它提供了丰富的源码实例,帮助读者深入理解iPhone应用的构建过程。这个压缩包包含的文件目录结构按照章节进行划分,方便读者按照...

    iPhone_and_iPad_开发实战

    《iPhone 和 iPad 开发实战》是一本专注于iOS应用开发的实践指南,旨在帮助读者深入理解并掌握使用Swift语言进行iOS应用开发的技术与方法。在这一领域,开发者们将学习到如何构建高质量、用户友好的应用程序,以适应...

    iPhone开发秘籍(The iphone developer cookbook)(第2版)(英文版)

    - **SQLite数据库应用**:教授如何在iPhone应用中集成SQLite数据库,实现高效的数据检索和管理。 #### 网络通信 - **网络编程基础**:涵盖HTTP请求、JSON解析、异步数据加载等网络编程基础知识。 - **WebSocket实战...

    The Definitive Guide to SQLite Second Edition.pdf

    书中还会对SQLite内部工作机制进行深入了解,并探索如何利用SQLite开发iOS(iPhone)和Android应用程序。SQLite是全世界成千上万种产品选择的解决方案,包括手机、GPS设备、机顶盒和网络浏览器等。实际上,你可能...

    iPhone开发基础教程_(美)Dave_Mark_中文高清版

    - **SQLite**:探索SQLite数据库的使用方法,包括查询、更新等基本操作。 - **文件系统访问**:理解如何读写文件,包括沙盒环境下的文件管理。 3. **网络通信** - **HTTP/HTTPS协议**:理解HTTP请求的基本原理及...

    iPhone3开发基础教程

    《iPhone3开发基础教程》是针对初学者的一本详尽指南,旨在引领读者探索iPhone SDK,深入了解iPhone和iPod touch编程。本书由Dave Mark与Jeff LaMarche共同编写,为第三版更新修订版,专为iOS开发新手设计,涵盖了...

    Professional iPhone and iPad Database Application Programming

    在iOS应用中集成SQLite,需要了解如何在Objective-C或Swift代码中操作SQLite数据库。书中将涵盖如何使用FMDB等第三方库来简化SQLite的API调用,以及如何在应用生命周期中正确管理和保存数据库状态。 三、核心数据...

    IPHONE开发的基础教程

    - **定义与背景**:iPhone开发是指在苹果公司的iOS操作系统上创建应用程序的过程,这涉及到使用特定的开发工具、语言和框架。自苹果推出iPhone以来,其独特的设计理念、优秀的用户体验和庞大的用户基数,使得iPhone...

Global site tag (gtag.js) - Google Analytics