一、数据库

在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等。离线缓存一般都是把数据保存到项目的沙盒中。有以下几种方式:

  1. 归档:NSKeyedArchiver
  2. 偏好设置:NSUserDefaults
  3. plist存储:writeToFile

上述的使用可以参考iOS学习笔记15-序列化、偏好设置和归档,但上述三种方法都有一个致命的缺点,那就是都无法存储大批量的数据,有性能的问题,在这个时候就是使用数据库的时候。

数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,用于存储管理大量的数据,可以高效的存储大批量数据,也可以高效的读取大批量数据,功能强大。

数据库的存储结构和excel很像,以表(table)为单位 。表由多个字段(列、属性、column)组成,表里面的每一行数据称为记录,但又不是简单的表格,还有表与表之间的关系,也就是现在主流的关系型数据库。

二、SQLite介绍

SQLite是一款轻型的嵌入式数据库,安卓和iOS开发使用的都是SQLite数据库。
它的特点:

  1. 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。
  2. 它的处理速度比MySQL、PostgreSQL这两款著名的数据库都还快。
  3. 它是C语言框架的,跨平台性强。

我们现在已经到了SQLite3时代了,后面的3是版本,现在我们就开始来使用它吧。

三、SQLite3的使用

一般常用的数据库操作有:【本章就以这5个步骤进行讲解】
  1. 创建数据库
  2. 创建表
  3. 向表插入数据
  4. 从表中读取数据
  5. 关闭数据库

要在iOS中使用SQLite3,需要在Xcode导入libsqlite3的库

上面两个其中一个都可以,然后我们还需要在项目中添加头文件和定义一个数据库句柄,这个数据库句柄控制数据库的所有操作。

1. 打开数据库

使用的C语言函数如下:
/* 打开数据库 */
int sqlite3_open(
const char *filename, /* 数据库路径(UTF-8) */
sqlite3 **pDb /* 返回的数据库句柄 */
);
下面是实例:
/* 打开数据库 */
- (void)openDatabase:(NSString *)dbname
{
//生成沙盒文件路径
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject];
NSString *filePath = [directory stringByAppendingPathComponent:dbname];
//打开数据库,如果数据库存在直接打开,如果数据库不存在,创建并打开
int result = sqlite3_open(filePath.UTF8String, &_database);
if (result == SQLITE_OK) {
NSLog(@"Open Database Success");
} else {
NSLog(@"Open Database Fail");
}
}

2. 执行没有返回值得SQL语句

使用的C语言函数:
/* 执行没有返回的SQL语句 */
int sqlite3_exec(
sqlite3 *db, /* 数据库句柄 */
const char *sql, /* SQL语句(UTF-8) */
int (*callback)(void*,int,char**,char**), /* 回调的C函数指针 */
void *arg, /* 回调函数的第一个参数 */
char **errmsg /* 返回的错误信息 */
);
使用实例:
/* 执行没有返回值的SQL语句 */
- (void)executeNonQuery:(NSString *)sql
{
if (!_database) {
return;
}
char *error;
//执行没有返回值的SQL语句
int result = sqlite3_exec(_database, sql.UTF8String, NULL, NULL, &error);
if (result == SQLITE_OK) {
NSLog(@"Execute SQL Query Success");
} else {
NSLog(@"Execute SQL Query Fail error : %s",error);
}
}

3.执行有返回值的SQL语句

使用的C语言函数:
/* 执行有返回结果的SQL语句 */
int sqlite3_prepare_v2(
sqlite3 *db, /* 数据库句柄 */
const char *zSql, /* SQL语句(UTF-8) */
int nByte, /* SQL语句最大长度,-1表示SQL支持的最大长度 */
sqlite3_stmt **ppStmt, /* 返回的查询结果 */
const char **pzTail /* 返回的失败信息*/
);
既然有返回结果,怎么处理返回结果,也有一些C语言函数:
#pragma mark - 定位记录的方法
/* 在查询结果中定位到一条记录 */
int sqlite3_step(sqlite3_stmt *stmt);
/* 获取当前定位记录的字段名称数目 */
int sqlite3_column_count(sqlite3_stmt *stmt);
/* 获取当前定位记录的第几个字段名称 */
const char * sqlite3_column_name(sqlite3_stmt *stmt, int iCol);
# pragma mark - 获取字段值的方法
/* 获取二进制数据 */
const void * sqlite3_column_blob(sqlite3_stmt *stmt, int iCol);
/* 获取浮点型数据 */
double sqlite3_column_double(sqlite3_stmt *stmt, int iCol);
/* 获取整数数据 */
int sqlite3_column_int(sqlite3_stmt *stmt, int iCol);
/* 获取文本数据 */
const unsigned char * sqlite3_column_text(sqlite3_stmt *stmt, int iCol);
使用实例:
/* 执行有返回值的SQL语句 */
- (NSArray *)executeQuery:(NSString *)sql
{
if (!_database) {
return nil;
}
NSMutableArray *array = [NSMutableArray array];
sqlite3_stmt *stmt; //保存查询结果
//执行SQL语句,返回结果保存在stmt中
int result = sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL);
if (result == SQLITE_OK) {
//每次从stmt中获取一条记录,成功返回SQLITE_ROW,直到全部获取完成,就会返回SQLITE_DONE
while( SQLITE_ROW == sqlite3_step(stmt)) {
//获取一条记录有多少列
int columnCount = sqlite3_column_count(stmt);
//保存一条记录为一个字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (int i = 0; i < columnCount; i++) {
//获取第i列的字段名称
const char *name = sqlite3_column_name(stmt, i);
//获取第i列的字段值
const unsigned char *value = sqlite3_column_text(stmt, i);
//保存进字典
NSString *nameStr = [NSString stringWithUTF8String:name];
NSString *valueStr = [NSString stringWithUTF8String:(const char *)value];
dict[nameStr] = valueStr;
}
[array addObject:dict];//添加当前记录的字典存储
}
sqlite3_finalize(stmt);//stmt需要手动释放内存
stmt = NULL;
NSLog(@"Query Stmt Success");
return array;
}
NSLog(@"Query Stmt Fail");
return nil;
}

4. 关闭数据库

使用的C语言函数:
/* 关闭数据库 */
int sqlite3_close(sqlite3 *db);
使用实例:
/* 关闭数据库 */
- (void)closeDatabase
{
//关闭数据库
int result = sqlite3_close(_database);
if (result == SQLITE_OK) {
NSLog(@"Close Database Success");
_database = NULL;
} else {
NSLog(@"Close Database Fail");
}
}

四、SQLite结合SQL语句

除了使用libsqlite库里的C语言函数还无法完成对数据库操作,还需要使用到SQL语句,就是一门控制数据库的语言【一个大知识】。

这里就简单列出一些常用的SQL语句:
  1. 创建表:
    create table 表名称(字段1,字段2,……,字段n,[表级约束])[TYPE=表类型];
  2. 插入记录:
    insert into 表名(字段1,……,字段n) values (值1,……,值n);
  3. 删除记录:
    delete from 表名 where 条件表达式;
  4. 修改记录:
    update 表名 set 字段名1=值1,……,字段名n=值n where 条件表达式;
  5. 查看记录:
    select 字段1,……,字段n from 表名 where 条件表达式;
下面是结合SQL语句完成数据库操作,使用到的是上面定义的方法:
/* 结合SQL语句,操作数据库 */
- (void)sqlite3Test{
//打开SQlite数据库
[self openDatabase:@"sqlite3_database.db"];
//在数据库中创建表
[self executeNonQuery:@"create table mytable(num varchar(7),name varchar(7),sex char(1),primary key(num));"];
//在表中插入记录
[self executeNonQuery:@"insert into mytable(num,name,sex) values (0,'liuting','m');"];
[self executeNonQuery:@"insert into mytable(num,name,sex) values (1,'zhangsan','f');"];
[self executeNonQuery:@"insert into mytable(num,name,sex) values (2,'lisi','m');"];
[self executeNonQuery:@"insert into mytable(num,name,sex) values (3,'wangwu','f');"];
[self executeNonQuery:@"insert into mytable(num,name,sex) values (4,'xiaoming','m');"];
//读取数据库的表中数据
NSArray* result = [self executeQuery:@"select num,name,sex from mytable;"];
if (result) {
for (NSDictionary *row in result) {
NSString *num = row[@"num"];
NSString *name = row[@"name"];
NSString *sex = row[@"sex"];
NSLog(@"Read Database : num=%@, name=%@, sex=%@",num,name,sex);
}
}
[self closeDatabase];
}
/* 修改一下,把原来存在的数据库文件删除掉,再创建并打开数据库 */
- (void)openDatabase:(NSString *)dbname
{
//生成沙盒文件路径
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject];
NSString *filePath = [directory stringByAppendingPathComponent:dbname];
//判断该文件在不在
NSFileManager *manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePath]){
//文件存在,就删除掉
[manager removeItemAtPath:filePath error:NULL];
}
//打开数据库,保持sqlite3数据库对象_database,返回值判别是否打开成功
int result = sqlite3_open(filePath.UTF8String, &_database);
if (result == SQLITE_OK) {
NSLog(@"Open Database Success");
} else {
NSLog(@"Open Database Fail");
}
}

如果你C语言基础比较好的话,是不是感到使用起来也没那么困难,但这样的使用缺少一些面向对象的思想,我们还是会有点不习惯,没关系,下一节我就会讲SQLite的一个轻量级封装第三方开源库FMDB,使得操作SQLite数据库变得方便,敬请期待!

iOS学习笔记16-数据库SQLite的更多相关文章

  1. Python学习笔记 使用数据库SQlite Mysql

    SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用当中, 甚至在IOS和Android的APP中都可以集成 Python就内 ...

  2. Laravel5.1学习笔记16 数据库2 查询构造器(这个不用看,不如用EloquentORM)

    Introduction Retrieving Results Aggregates Selects Joins Unions Where Clauses Advanced Where Clauses ...

  3. golang学习笔记16 beego orm 数据库操作

    golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...

  4. SQL反模式学习笔记16 使用随机数排序

    目标:随机排序,使用高效的SQL语句查询获取随机数据样本. 反模式:使用RAND()随机函数 SELECT * FROM Employees AS e ORDER BY RAND() Limit 1 ...

  5. IOS学习笔记48--一些常见的IOS知识点+面试题

      IOS学习笔记48--一些常见的IOS知识点+面试题   1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...

  6. iOS学习笔记17-FMDB

    上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...

  7. iOS学习笔记17-FMDB你好!

    上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...

  8. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  9. MongoDB学习笔记:MongoDB 数据库的命名、设计规范

    MongoDB学习笔记:MongoDB 数据库的命名.设计规范     第一部分,我们先说命名规范. 文档 设计约束 UTF-8 字符 不能包含 \0 字符(空字符),这个字符标识建的结尾 . 和 $ ...

随机推荐

  1. iOS --runtime理解

    iOS~runtime理解 Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下,一为 查阅方便二为 或许能给 ...

  2. afnetworking NSCocoaErrorDomain Code=3840 解决

    afnetworking json解析出错 解决方法1 AFURLResponseSerialization.m 258行修改 responseString = [responseString str ...

  3. keras中的shape/input_shape

    在keras中,数据是以张量的形式表示的,张量的形状称之为shape,表示从最外层向量逐步到达最底层向量的降维解包过程.“维”的也叫“阶”,形状指的是维度数和每维的大小.比如,一个一阶的张量[1,2, ...

  4. LeetCode || 递归 / 回溯

    呜呜呜 递归好不想写qwq 求“所有情况”这种就递归 17. Letter Combinations of a Phone Number 题意:在九宫格上按数字,输出所有可能的字母组合 Input: ...

  5. shell脚本,awk 匹配的做修改后打印,不匹配的打印。

    文件file内容如下a 1a 2b 3b 4 b 5c 6c 7 要求:第一列匹配b时,如果第二列大于3,那么将第二列加上1后打印,其余的原封不动打印.结果如下: a 1a 2b 3b 5 b 6c ...

  6. 计算机应用第七次作业 html制作个人音乐播放站点

    计算机应用第七次作业 html制作个人音乐播放站点 请访问下边网址查看具体操作: http://www.cnblogs.com/qingyundian/p/7878892.html

  7. EAGLView介绍

    http://book.51cto.com/art/201108/285446.htm

  8. 哪些 Python 库让你相见恨晚?

    知乎用户,A European Swallow. 苇叶.Aran He.jerry等人赞同 补充三个有助于自动化日常工作的: sh:sh 1.08 — sh v1.08 documentation可以 ...

  9. 微信小程序 wx.request POST请求------中文乱码问题

    问题: 一个简单的表单,提交后台返回数据“提交成功”. 以为没问题了,但是没过多久后台小哥就问为啥那么多乱码,找了很久原因,发现在提交的时候就已经乱码了. 嗯,前端问题,然后测试GET/POST方法. ...

  10. Git学习——把文件推送到远程仓库

    本地仓库与GitHub仓库关联 git remote add origin git@github.com:<github账户名>/<github的仓库名>.git 把本地库的所 ...