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, );
const unsigned char *t_name = sqlite3_column_text(stmt1, );
NSString *name = [NSString stringWithUTF8String:(char*)t_name];
NSLog(@"%i %@",t_id,name);
}
//释放stmt statement
sqlite3_finalize(stmt1); //<五>查询数据2 参数化的sql语句 查找id>2 并且名字以p开头的
//用?占位
int seachId2 = ;
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, );
const unsigned char *t_name = sqlite3_column_text(stmt6, );
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], -, &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], -, &stmt, NULL);
if (pre_res == SQLITE_OK) {
//有参数,循环绑定参数
if (params!=nil) {
for (int i=; i<params.count; i++) { id obj = params[i];
//绑定的数据类型可能为NSString或者NSNumber,或者数据为空,分别判断
if (obj==nil) {
//如果数据为nil
sqlite3_bind_null(stmt, i+);
}
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+, [obj intValue]);
}
else if (strstr("fdFD", [obj objCType]))
{
sqlite3_bind_double(stmt, i+, [obj doubleValue]);
}
else
{
stmt = nil;
}
}
else if ([obj respondsToSelector:@selector(UTF8String)])
{
//当前的绑定的数据类型位NSString 判断是否有UTF8String方法
//用bind替换占位符 索引从1开始
sqlite3_bind_text(stmt, i+, [obj UTF8String], -, NULL);
}
else
{
stmt = nil;
}
} return stmt;
}
} return NULL;
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
} @end
疑问咨询或技术交流,请加入官方QQ群: (452379712)
出处:http://www.cnblogs.com/jerehedu/
本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
IOS 数据存储之 SQLite详解的更多相关文章
- IOS 数据存储之 FMDB 详解
FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语言API,使用起来更加的方便,不需要过 ...
- Android开发数据存储之ContentProvider详解
转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可 ...
- IOS数据存储之Sqlite数据库
前言: 之前学习了数据存储的NSUserDefaults,归档和解档,沙盒文件存储,但是对于数据量比较大,需要频繁查询,删除,更新等操作的时候无论从效率上还是性能上,上述三种明显不能满足我们的日常开发 ...
- IOS 数据存储之 SQLite具体解释
在IOS开发中常常会须要存储数据,对于比較少量的数据能够採取文件的形式存储,比方使用plist文件.归档等,可是对于大量的数据,就须要使用数据库,在IOS开发中数据库存储能够直接通过SQL訪问数据库, ...
- iOS SQLite详解
这周比较忙,前几天都加班到11点左右,基本都是到家都是12点左右(稍稍的抱怨一下,免费加班,何为免费,就是任何补偿都没有,例如调休,加班薪,餐补等各项福利,是一点都没有呀)因为App要上线了!App上 ...
- iOS中MVC等设计模式详解
iOS中MVC等设计模式详解 在iOS编程,利用设计模式可以大大提高你的开发效率,虽然在编写代码之初你需要花费较大时间把各种业务逻辑封装起来.(事实证明这是值得的!) 模型-视图-控制器(MVC)设计 ...
- IOS数据库操作SQLite3使用详解(转)
iPhone中支持通过sqlite3来访问iPhone本地的数据库.具体使用方法如下1:添加开发包libsqlite3.0.dylib首先是设置项目文件,在项目中添加iPhone版的sqlite3的数 ...
- 《iOS 7 应用开发实战详解》
<iOS 7 应用开发实战详解> 基本信息 作者: 朱元波 管蕾 出版社:人民邮电出版社 ISBN:9787115343697 上架时间:2014-4-25 出版日期:2014 年5 ...
- Code First开发系列之管理数据库创建,填充种子数据以及LINQ操作详解
返回<8天掌握EF的Code First开发>总目录 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LINQ to ...
随机推荐
- exe4j中"this executable was created with an evaluation version exe4j"的解决
在使用exe4j时,如果您的exe4j没有注册,在运行有exe4j转换的*.jar为*.exe的可执行文件时,会提示:"this executable was created with an ...
- uva12436 回头再做一次
线段树维护等差数列,结点维护首项+公差即可 #include <cstdio> #include <cstring> #include <algorithm> us ...
- 《剑指offer》-左旋转字符串
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S="abc ...
- 接口隔离原则(Interface Segregation Principle, ISP)
使用多个专门的接口,而不使用单一的总接口 接口隔离有两种定义: Clients should not be forced to depend upon interfaces that they don ...
- Spring之对象依赖关系(依赖注入Dependency Injection)
承接上篇: Spring中,如何给对象的属性赋值: 1:通过构造函数,如下所示: <!-- 1:构造函数赋初始值 --><bean id="user1" clas ...
- Storm(三)Storm的原理机制
一.Storm的数据分发策略 1. Shuffle Grouping 随机分组,随机派发stream里面的tuple,保证每个bolt task接收到的tuple数目大致相同. 轮询,平均分配 2. ...
- 在vs2008工程中制作cab包
内容转自MSDN 1.首先,制作自己的智能设备工程 2.添加cab工程: 为解决方案添加智能设备 CAB 项目 打开现有的智能设备项目,并确保“解决方案资源管理器”可见. 在“文件”菜单上指向“添加” ...
- Python之禅的翻译和解释
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit ...
- pandas学习(创建数据,基本操作)
pandas学习(一) Pandas基本数据结构 Series类型数据 Dataframe类型 基本操作 Pandas基本数据结构 两种常用数据结构: Series 一维数组,与Numpy中的一维ar ...
- IdentityServer4-EF动态配置Client和对Claims授权(二)
本节介绍Client的ClientCredentials客户端模式,先看下画的草图: 一.在Server上添加动态新增Client的API 接口. 为了方便测试,在Server服务端中先添加swagg ...