iOS_数据存取(二)
本节内容目录:
一、SQLite3
二、Core Data
一、SQlite3
SQLite3是⼀款开源的嵌入式关系型数据库,可移植性好、易使用、内存开销小
SQLite3是⽆类型的,意味着你可以保存任何类型的数据到任意表的任意字段中。⽐如下列的创表语句是合法的:
create table t_person(name, age);
为了保证可读性,建议还是把字段类型加上:
create table t_person(name text, age integer);
#import "ViewController.h"
#import <sqlite3.h>
@interface ViewController ()
{
sqlite3 *_db;
}
@end
@implementation ViewController
-(void)queryAll
{
//准备结果集
sqlite3_stmt *pStmt = NULL;
/*
第一个参数为sqlite3 *类型,为指向sqlite3_open()类函数打开的数据库连接。
第二个参数为需要编译成字节码的sql语句。如果输入的参数有多条sql语句,只有第一个SQL语句被编译。
第三个参数,若为小于0的值,系统会自动读取第一个参数一直到出现字符结束符。若该参数大于0,则它表明要读入的SQL的最大的程度,建议设置其值为sql语句的字节数加上字符结束符后的值,此时执行的效率会有提升。
第四个参数,返回编译好的sqlite3_stmt指针,若第一个参数不包含SQL语句或传进来的SQL语句有错,则此函数返回时被置为NULL。
第五个参数若不为NULL,则它会指向第一条SQL语句结尾后面的第一个字节。这个参数用于指向剩下的未编译的语句。
*/
sqlite3_prepare_v2(_db, "select *from user", -, &pStmt, NULL);
while (sqlite3_step(pStmt) == SQLITE_ROW) {
//取出对应列的字段值,
int ID = sqlite3_column_int(pStmt, );
const unsigned char *name = sqlite3_column_text(pStmt, );
const unsigned char *password = sqlite3_column_text(pStmt, );
NSLog(@"%d,%s,%s",ID,name,password);
}
}
-(void)execSql:(NSString *)sql
{
char *errorMsg = nil;
/*
第一个参数为sqlite3 *类型。通过sqlite3_open()函数得到
第二个参数是一个指向一个字符串的指针,该字符串的内容为一条完整的SQL语句(不需要在语句结束后加";"),字符串都是以/0结尾的,这个也不例外。
第三个参数为一个回调函数,当这条语句执行之后,sqlite3会去调用这个函数。其原型为
typedef int (*sqlite_callback)(void *,int,char **colvalue,char **colname);
第四个参数为提供给回调函数的参数。如果不需要传递参数,则可以写为NULL。
第五个参数为错误信息。注意,是指针的指针。通过打印printf("%s\n",errmsg),可以知道错误发生在什么地方。
*/
sqlite3_exec(_db, [sql UTF8String], nil, nil, &errorMsg);
if (errorMsg) {
NSLog(@"执行失败:%s",errorMsg);
}
else
{
NSLog(@"执行成功");
}
}
- (void)viewDidLoad {
[super viewDidLoad];
//拼接数据库保存路径
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [documents lastObject];
NSString *dbName = [path stringByAppendingPathComponent:@"test.db"]; //打开数据库
if (sqlite3_open([dbName UTF8String], &_db) == SQLITE_OK) {
//创建表
[self execSql:@"create table user(ID integer,name text,password text)"];
//插入两条新纪录
[self execSql:@"insert into user values(1,'admin','123456')"];
[self execSql:@"insert into user values(2,'guest','123456')"];
//查询记录
[self queryAll];
//更新记录
[self execSql:@"update user set password = password + 10 where name = 'admin'"];
[self queryAll];
//关闭数据库
sqlite3_close(_db);
}
else
{
NSLog(@"打开失败");
}
}
@end
以上案例中通过C语言函数的形式实现了简单地Sqlite基本操作,这并不符合面向对象程序设计的基本思想,接下来案例中,通过自定义对象来创建数据库。
Student.h头文件代码如下: #import <Foundation/Foundation.h> @interface Student : NSObject
@property(assign,nonatomic)NSInteger ID;
@property(copy,nonatomic)NSString *name;
@property(assign,nonatomic)int age;
@property(assign,nonatomic)char gender;
@property(assign,nonatomic)float chineseScore;
@property(assign,nonatomic)float mathScore;
@property(assign,nonatomic)float englishScore;
@end Student.m代码如下:
#import "Student.h" @implementation Student
-(NSString *)description
{
return [NSString stringWithFormat:@"%ld,%@,%d,%c,%.2f,%.2f,%.2f",_ID,_name,_age,_gender,_chineseScore,_mathScore,_englishScore];
}
@end
以上代码,构建了Student模型。
StudentDAO.h头文件代码如下:
#import <Foundation/Foundation.h>
#import <sqlite3.h>
@class Student;
@interface StudentDAO : NSObject
{
sqlite3 *_db;
}
+(StudentDAO *)shardManger;
//初始化:创建表,添加数据;
-(void)initDataBase;
//添加学生记录
-(BOOL)addStudent:(Student *)student;
//删除学生记录
-(BOOL)deleteStudentByName:(NSString *)name;
//更新学生记录
-(BOOL)updateStudent:(Student *)student;
//查询学生记录
-(NSArray *)queryStudentAll;
-(Student*)queryStudentByName:(NSString *)name;
@end
StudentDAO.m代码如下:
#import "StudentDAO.h"
#import "Student.h"
#import <sqlite3.h>
static StudentDAO *instace = nil;
@implementation StudentDAO
//创建单例对象,确保数据库只被初始化一次,
+(StudentDAO *)shardManger
{
static dispatch_once_t once;
dispatch_once(&once,^{
instace = [StudentDAO new];
[instace initDataBase];
});
return instace;
}
//拼接数据库路径
-(NSString *)dbPath
{
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [documents lastObject];
return [path stringByAppendingPathComponent:@"test.db"];
}
//此方法会多次被调用,用户创建表
-(BOOL)execSql:(NSString *)sql
{
char *errorMsg = NULL;
//参数详解,请参考⬆️上个案例
sqlite3_exec(_db, [sql UTF8String], nil, nil, &errorMsg);
if (errorMsg)
{
NSLog(@"执行失败:%s",errorMsg);
return NO;
}
else
{
NSLog(@"执行成功");
return YES; }
}
-(void)initDataBase
{
//打开数据库
if (sqlite3_open([[self dbPath]UTF8String], &_db) == SQLITE_OK)
{
//创建表
if ([self execSql:@"create table student (ID integer primary key autoincrement,name text,age integer,gender integer,chineseScore real,mathScore real,englishScore real)"])
{
for (int i = ; i < ; i++)
{
Student *stu = [[Student alloc]init];
stu.name = [NSString stringWithFormat:@"name%d",i+];
stu.age = +i;
stu.gender = (i % == ? 'F':'M');
stu.chineseScore = +i;
stu.mathScore = +i;
stu.englishScore = +i;
[self addStudent:stu]; }
}
}
sqlite3_close(_db);
}
//添加学生记录
-(BOOL)addStudent:(Student *)student
{
NSString *insertSql = @"insert into student(name text,age integer,gender integer,chineseScore real,mathScore real,englishScore real)";
sqlite3_stmt *pStmt = nil;
if (sqlite3_prepare_v2(_db, [insertSql UTF8String], -, &pStmt, nil) == SQLITE_OK)
{
//使用sqlite3_bind_xxx()对字段进行绑定,通配符与绑定的字段一一对应。序号从1开始。
sqlite3_bind_text(pStmt, , [student.name UTF8String], -, NULL);
sqlite3_bind_int(pStmt, , student.age);
sqlite3_bind_int(pStmt, , student.gender);
sqlite3_bind_double(pStmt, , student.chineseScore);
sqlite3_bind_double(pStmt, , student.mathScore);
sqlite3_bind_double(pStmt, , student.englishScore);
// SQLITE_DONE:SQL语句执行完成
if (sqlite3_step(pStmt) == SQLITE_DONE)
{
return YES;
}
//释放结果集
sqlite3_finalize(pStmt);
}
return NO;
}
//更新学生记录
-(BOOL)updateStudent:(Student *)student
{
NSString *updateSql = @"update student set math = ? where name = ?";
//准备结果集
sqlite3_stmt *pStmt = NULL;
if (sqlite3_prepare_v2(_db, [updateSql UTF8String], -, &pStmt, NULL)== SQLITE_OK)
{
sqlite3_bind_int(pStmt, , student.mathScore);
sqlite3_bind_text(pStmt, , [student.name UTF8String], -, NULL);
if (sqlite3_step(pStmt) == SQLITE_DONE)
{
return YES;
}
}
//清理结果集
sqlite3_finalize(pStmt);
return NO;
} //通过姓名进行删除
-(BOOL)deleteStudentByName:(NSString *)name
{
NSString *deleteSql = @"delete from student where name = ?";
sqlite3_stmt *pStmt = NULL;
if (sqlite3_prepare_v2(_db, [deleteSql UTF8String], -, &pStmt, nil) == SQLITE_OK)
{
sqlite3_bind_text(pStmt, , [name UTF8String], -, NULL);
if (sqlite3_step(pStmt) == SQLITE_OK)
{
return YES;
}
}
sqlite3_finalize(pStmt);
return NO;
}
//查询学生记录
-(NSArray *)queryStudentAll
{
NSMutableArray *array = [NSMutableArray array];
//准备结果集
sqlite3_stmt *pStmt = NULL;
if (sqlite3_prepare_v2(_db, [@"select * from student" UTF8String], -, &pStmt, NULL) == SQLITE_OK)
{
//遍历结果集
while (sqlite3_step(pStmt) == SQLITE_ROW)
{ Student *stu = [[Student alloc]init];
stu.ID = sqlite3_column_int(pStmt, );
stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, )];
stu.age = sqlite3_column_int(pStmt, );
stu.gender = sqlite3_column_int(pStmt, );
stu.chineseScore = sqlite3_column_double(pStmt, );
stu.mathScore = sqlite3_column_double(pStmt, );
stu.englishScore = sqlite3_column_double(pStmt, ); [array addObject:stu];
}
}
//清理结果集
sqlite3_finalize(pStmt);
return array;
}
//通过姓名进行查找
-(Student *)queryStudentByName:(NSString *)name
{
NSString *sql = @"select * from student where name = ?";
//准备结果集
sqlite3_stmt *pStmt = NULL;
if (sqlite3_prepare_v2(_db,[sql UTF8String], -, &pStmt, NULL) == SQLITE_OK) {
sqlite3_bind_text(pStmt, , [name UTF8String], -, NULL);
//执行语句
if(sqlite3_step(pStmt)== SQLITE_ROW)
{
Student *stu = [Student new];
// 使用sqlite3_column_xxx()进行获取某列的字段值。
stu.ID = sqlite3_column_int(pStmt, );
stu.name = [NSString stringWithFormat:@"%s",sqlite3_column_text(pStmt, )];
stu.age = sqlite3_column_int(pStmt, );
stu.gender = sqlite3_column_int(pStmt, );
stu.chineseScore = sqlite3_column_double(pStmt, );
stu.mathScore = sqlite3_column_double(pStmt, );
stu.englishScore = sqlite3_column_double(pStmt, ); return stu;
}
}
sqlite3_finalize(pStmt);
return nil;
}
@end
以下内容是从网络中摘抄的一些东西,供大家学习参考。
{
else
{
NSLog(@"执行成功");
2】参数说明:
NSString *documentPath = [document lastObject];
SQLite支持的常见数据类型如下所示。
- INTEGER 有符号的整数类型
- REAL 浮点类型
- TEXT 字符串类型,采用UTF-8和UTF-16字符编码
- BLOB 二进制大对象类型,能够存放任何二进制数据
iOS_数据存取(二)的更多相关文章
- iOS_数据存取(一)
目录: 一.沙盒机制 二.用户偏好设置 三.归档 一.沙盒机制 每个iOS应⽤都有⾃己的应用沙盒(应⽤沙盒就是⽂件系统⽬录),与其他文件系统隔离.应⽤必须待在⾃己的沙盒⾥,其他应用不能访问该应用沙盒的 ...
- JavaScript数据存取的性能问题
JavaScript中四种基本的数据存取位置: 字面量:只代表自身 字符串.数字.布尔值.对象.函数.数组.正则,以及null和undefined 快 本地变量:var定义的 快 数组元素 ...
- 高性能JS笔记2——数据存取
数据存取性能而言: 字面量>本地变量>数组元素>对象成员 一.标识符解析的性能 标识符解析是有代价的,一个标识符的位置越深,它的读写速度也就越慢. 局部变量的读写速度是最快的,全局变 ...
- 使用文本文件(.txt)进行数据存取的技巧总结(相当的经典)
使用文本文件(.txt)进行数据存取的技巧总结(相当的经典) 使用文本文件(.txt)进行数据存取的技巧总结 由于本帖内容较多,部分转自他人的心得,因此,凡转贴的地方仅用“----转----”标注,原 ...
- 数据分析与展示——NumPy数据存取与函数
NumPy库入门 NumPy数据存取和函数 数据的CSV文件存取 CSV文件 CSV(Comma-Separated Value,逗号分隔值)是一种常见的文件格式,用来存储批量数据. np.savet ...
- go 多维度 Map 的数据存取
多维度 Map 的数据存取 一维情况下的 map 做存取很简单,而二维以上的情况就得小心了. 先来看一个例子: m:=make(map[string]map[string]int) c:=make ...
- Numpy数据存取
Numpy数据存取 numpy提供了便捷的内部文件存取,将数据存为np专用的npy(二进制格式)或npz(压缩打包格式)格式 npy格式以二进制存储数据的,在二进制文件第一行以文本形式保存了数据的元信 ...
- Python数据分析与展示(1)-数据分析之表示(2)-NumPy数据存取与函数
NumPy数据存取与函数 数据的CSV文件存取 CSV文件 CSV(Comma-Separated Value,逗号分隔值) CSV是一种常见的文件格式,用来存储批量数据. 将数据写入CSV文件 np ...
- Python——NumPy数据存取与函数
1.数据csv文件存贮 1.1 CSV文件写入 CSV (Comma‐Separated Value, 逗号分隔值)CSV是一种常见的文件格式,用来存储批量数据 np.savetxt(frame, a ...
随机推荐
- Android 编程之入门开发目录管理器开发抽屉与文件分类-4
在此目录管理APP里,我们能够尝试引用一些新的元素.在这里我给打击介绍一个叫抽屉的布局,QQ就用到了抽屉布局.不 过他们又在原有的基础上自己开发了新的抽屉布局.而且还蛮高大上的,顺便说说分类管理.这些 ...
- linux下Java运行时so文件的附加
将路径加入至 etc/ld.so.conf 中
- ssh 面试
Struts1工作原理1. 初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总 控制器会读取配置文件(st ...
- day1笔记 初识python,paython基础
一.计算机,操作系统 软件发送指令给操作系统,操作系统再把指令发送给 内存,cpu,硬盘等 二.Python的历史. Python2: 1.臃肿,源码的重复量很多.2.语法不清晰,掺杂着c,++,P ...
- PHP中foreach详细解读
oreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息.有两种语法: foreach (array_ ...
- react手记(componentWillMount,componentDidMount等)
生命周期componentWillMount 组件出现前 就是dom还没有渲染到html文档里面componentDidMount 组件渲染完成 已经出现在dom文档里可以再各个周期实现特定的操作 生 ...
- Youth Is Not a Time of Life
Youth is not a time of life; it is a state of mind.青春不是年华,而是心境: It is not a matter of rosy cheeks, r ...
- Consul文档收藏
英文:https://www.consul.io/intro/getting-started/install.html 中文:http://www.liangxiansen.cn/2017/04/06 ...
- phpwind 论坛 转移
前段时间用phpwind 搭建了一个本地论坛系统,也写过一篇随笔,讲phpwind论坛的迁移,昨天网上又对论坛做了迁移,在本地搭建了系统. 使用的是之前没有成功的方法.这种方法挺方便的,之前每次都是重 ...
- 使用QFile进行文件操作(QFile可以使用FILE *指针,还必须指定AutoCloseHandle)
QFile类我我们提供了操作文件的常用功能.它是一种io设备,可以用来读写文本文件和二进制文件,也可以用来读写Qt的资源文件.QFile类可以单独使用,该类本身提供了read/write函数,但更方便 ...