SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至今已经有14个年头,SQLite也迎来了一个版本 SQLite 3已经发布。

SQLite的特性

1. ACID事务

ACID,是指在可靠数据库管理系统(DBMS)中,事务(transaction)所应该具有的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability). 原子性意味着数据库中的事务执行是作为原子。即不可再分,整个语句要么执行,要么不执行。一致性指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款总额为2000元。事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

2. 零配置 – 无需安装和管理配置

3.储存在单一磁盘文件中的一个完整的数据库

4.数据库文件可以在不同字节顺序的机器间自由的共享

5.支持数据库大小至2TB

6. 足够小, 大致13万行C代码, 4.43M

7. 比一些流行的数据库在大部分普通数据库操作要快

8. 简单, 轻松的API

9. 包含TCL绑定, 同时通过Wrapper支持其他语言的绑定

10. 良好注释的源代码, 并且有着90%以上的测试覆盖率

11. 独立,没有额外依赖

12. 源码完全的开源, 你可以用于任何用途, 包括出售它

13. 支持多种开发语言,C, PHP, Perl, Java, C#,Python, Ruby

SQLite在iOS中的基本使用

在iOS开发中可以用一些SQLite数据库管理工具,例如SQLiteManager。

接下来就通过代码来讲述iOS中如何使用sqlite

sqlite.h文件的引入

首先是打开和关闭数据库,打开和创建数据库都是sqlite3_open函数,如果filename已经创建那就是打开。

NSString *filename;//数据库文件路径
sqlite3 *database; //sqlite3数据库句柄的指针
//打开数据库
- (int) open{
int rc=sqlite3_open([filename UTF8String], &database);
if (rc) {
sqlite3_close(database);
NSLog(@"open database failed");
}
return rc;
}
//关闭数据库
- (void) close{
if (database!=NULL) {
sqlite3_close(database);
}
}
接下来插入、删除、更新都是用sqlite3_exec函数,记住执行语句,必须要先打开数据库,完成之后需要关闭数据库。
//执行 insert,update,delete 等非查询SQL语句
- (int)executeNonQuery:(NSString *)sql error:(NSError **)error {
int rc;
char *errmsg;
rc = [self open];
if (rc) { 
//错误处理
if (error != NULL) {
NSDictionary *eDict =
[NSDictionary dictionaryWithObject:@"open database failed"
forKey:NSLocalizedDescriptionKey];
*error =
[NSError errorWithDomain:kSqliteErrorDomain code:rc userInfo:eDict];
}
return rc;
}
rc = sqlite3_exec(database, [sql UTF8String], NULL, NULL, &errmsg);
if (rc != SQLITE_OK) {
if (error != NULL) {
NSDictionary *eDict =
[NSDictionary dictionaryWithObject:@"exec sql error"
forKey:NSLocalizedDescriptionKey];
*error =
[NSError errorWithDomain:kSqliteErrorDomain code:rc userInfo:eDict];
}
NSLog(@"%s", errmsg);
sqlite3_free(errmsg);
}
[self close];
return rc;
}

上面函数中sqlite3_free就是释放存放错误信息的内存空间。查询操作会略显复杂,同样需要有开关数据库的操作,不过有一个准备结果集和最后释放结果集的操作,分别是sqlite3_prepare_v2和sqlite3_finalize,sqlite3_stmt就是结果集,下面就是具体操作。

[self open];
// 查
strsql = "select * from users";
// SQLITE_API int sqlite3_prepare_v2(
// sqlite3 *db, /* Database handle */
// const char *zSql, /* SQL statement*/
// int nByte, /* 结果集的最大长度。*/
// sqlite3_stmt **ppStmt, /* OUT: 结果集 */
// const char **pzTail /* OUT:指向结果集没有用到的内存部分的指针。 */
// );
sqlite3_stmt* rc;//陈述式句柄
if (sqlite3_prepare_v2(db, strsql, -1, &rc, NULL)!=SQLITE_OK) {
}
// sqlite3_step讲结果集数据指针指向下一个元素。
// 这个函数的返回值如果是SQLITE_ROW就表示我们的结果集里面有数据。
// 否则我们的结果集就是空的。
while (sqlite3_step(rc)==SQLITE_ROW) {
// sqlite3_column系列函数。一般有两个输入参数。第一个是结果集指针,第二是数据所在列的序号。
// 比如我们现在用的sqlite3_column_int和sqlite3_column_text。
printf("id:%d | username:%s | password:%s \n",sqlite3_column_int(rc, 0),sqlite3_column_text(rc, 1),sqlite3_column_text(rc, 2));
}
// 查完后一定要释放结果集。
sqlite3_finalize(rc);
[self close];

数据库加密

免费版的SQLite有一个致命缺点:不支持加密。这就导致存储在SQLite中的数据可以被任何人用任何文本编辑器查看到。

对数据库加密的思路有两种:

1. 将内容加密后再写入数据库

这种方式使用简单,在入库/出库只需要将字段做对应的加解密操作即可,一定程度上解决了将数据赤裸裸暴露的问题。

不过这种方式并不是彻底的加密,因为数据库的表结构等信息还是能被查看到。另外写入数据库的内容加密后,搜索也是个问题。

2. 对数据库文件加密

将整个数据库整个文件加密,这种方式基本上能解决数据库的信息安全问题。目前已有的SQLite加密基本都是通过这种方式实现的。这里就介绍一个开源的加密工具SQLCipher,安装方法可以参照官网文档,https://www.zetetic.net/sqlcipher/ios-tutorial/,SQLCipher使用256-bit AES加密,由于其基于免费版的SQLite,主要的加密接口和SQLite是相同的,但也增加了一些自己的接口。

其实SQLite的两个加密函数使用起来非常的简单,下面分情况说明:

1 给一个未加密的数据库添加密码:如果想要添加密码,则可以在打开数据库文件之后,关闭数据库文件之前的任何时刻调用sqlite3_key函数即可,该函数有三个参数,其中第一个参数为数据库对象,第二个参数是要设定的密码,第三个是密码的长度。例如:sqlite3_key(db,”1q2w3e4r”,8); //给数据库设定密码1q2w3e4r

2 读取一个加密数据库中的数据:完成这个任务依然十分简单,你只需要在打开数据库之后,再次调用一下sqlite3_key函数即可,例如,数据库密码是123456时,你只需要在代码中加入sqlite3_key(db,”123456″,6);

3更改数据库密码:首先你需要使用当前的密码正确的打开数据库,之后你可以调用sqlite3_rekey(db,”112233″,6) 来更改数据库密码。

4 删除密码:也就是把数据库恢复到明文状态。这时你仍然只需要调用sqlite3_rekey函数,并且把该函数的第二个参数置为NULL或者””,或者把第三个参数设为0。

事务操作

那么问题又来了,如果iOS的sqlite同时插入或者查询10000条数据,你该怎么办?

这里有三步要做,第一,减少开关数据库操作,插入10000条数据,不能开关10000次数据库,只能进行一次开关;

第二,就是不能放在主线程;

第三,最重要的一点就是加入事务操作。

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。所以10000次磁盘操作可能几分钟都做不完,这个时候需要把10000条语句都封装成一个事务。

下面就是开始事务和提交事务的代码了

-(int)beginService{
char *errmsg;
int rc = sqlite3_exec(database, "BEGIN transaction", NULL, NULL, &errmsg);
return rc;
}
-(int)commitService{
char *errmsg;
int rc = sqlite3_exec(database, "COMMIT transaction", NULL, NULL, &errmsg);
return rc;}

接下来就把三个操作合并

-(int)addModelsTest:(NSArray *)models error:(NSError **) error{
char *errmsg;
__block NSMutableArray *sqls=[NSMutableArray array];
__block NoticeModel *aModel=[[NoticeModel alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i=0; i<100000; i  ) {
aModel=[models objectAtIndex:0];
NSString *sql=[NSString stringWithFormat:@"insert into notices values('%lf','%d','%@','%@','%@','%d','%d','%d','%d','%@')",aModel.myID,aModel.news_id,aModel.news_title,aModel.content,aModel.pic,aModel.sort,aModel.record_status,aModel.counter,aModel.suid,aModel.publish_time];
[sqls addObject:sql];
}
int r1=[self open];
[self beginService];
int rc;
int i;
for (i=0; i<100000; i  ) {
rc=sqlite3_exec(database, [[sqls objectAtIndex:i] UTF8String], NULL, NULL, &errmsg);
}
[self commitService];
[self close];
if (i ==100000) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"call back, the data is: %@", i);
});
} else {
NSLog(@"error when download:%@", error);
}
});
return 0;
}

有关iOS中SQLite使用教程小编就给大家介绍这么多,希望对大家有所帮助!

iOS中SQLite使用教程的更多相关文章

  1. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  2. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  4. ios – Testflight无法安装应用程序

    我有几个测试人员注册了testflight并连接了他们的设备……他们有不同的ios型号……但是所有这些都有同样的问题.当他们从“safari”或“testflight”应用程序本身单击应用程序的安装按钮时……达到约90%并出现错误消息…

  5. ibm-mobilefirst – 在iOS 7.1上获取“无法安装应用程序,因为证书无效”错误

    当我的客户端将他们的设备更新到iOS7.1,然后尝试从AppCenter更新我们的应用程序时,我收到了上述错误.经过一番搜索,我找到了一个类似问题的帖子here.但是后来因为我在客户端使用AppCenter更新应用程序的环境中,我无法使用USB插件并为他们安装应用程序.在发布支持之前,是否有通过AppCenter进行下载的解决方法?

  6. ios – 视图的简单拖放?

    我正在学习iOS,但我找不到如何向UIView添加拖放行为.我试过了:它说“UIView没有可见的接口声明选择器addTarget”此外,我尝试添加平移手势识别器,但不确定这是否是我需要的它被称为,但不知道如何获得事件的坐标.在iOS中注册移动事件回调/拖放操作的标准简单方法是什么?

  7. PhoneGap / iOS上的SQLite数据库 – 超过5mb可能

    我误解了什么吗?Phonegap中的sqlitedbs真的有5mb的限制吗?我正在使用Phonegap1.2和iOS5.解决方法您可以使用带有phonegap插件的原生sqliteDB,您将没有任何限制.在iOS5.1中,Websql被认为是可以随时删除的临时数据…

  8. ios – 什么控制iTunes中iPhone应用程序支持的语言列表?

    什么控制iPhone应用程序的iTunes页面中支持的语言?

  9. ios – 获得APNs响应BadDeviceToken或Unregistered的可能原因是什么?

    我知道设备令牌在某些时候是有效的.用户如何使其设备令牌变坏?从关于“未注册”的文档:Thedevicetokenisinactiveforthespecifiedtopic.这是否意味着应用程序已被删除?.您应该看到四种分发方法:如果您选择AppStore或Enterprise,您将在后面的对话框中看到Xcode将APNS权利更改为生产:如果选择AdHoc或Development,则aps-environment下的文本将是开发,然后应与后端的配置匹配.

  10. ios – 当我关闭应用程序时,我从调试器获得消息:由于信号15而终止

    我怎么能解决这个问题,我不知道这个链接MypreviousproblemaboutCoredata对我的问题有影响吗?当我cmd应用程序的Q时,将出现此消息.Messagefromdebugger:Terminatedduetosignal15如果谁知道我以前的问题的解决方案,请告诉我.解决方法>来自调试器的消息:每当用户通过CMD-Q(退出)或STOP手动终止应用程序(无论是在iOS模拟器中还是

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部