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 ...
随机推荐
- 项目实战:JSP应用开发_接口:接口的实现
在类的声明中使用implements关键字来实现接口,一个类可以同时实现多个接口,各接口间用“,”隔开. class classname implements interfacename{ //重 ...
- ios . -- UICollectionView --cell 自适应
#pragma mark — 视图控制器中使用:(关键) layout.estimatedItemSize = CGSizeMake(WIDTH, ); // layout约束这边必须要用estima ...
- 安装使用yarn,使用国内镜像加速npm和yarn
安装yarn https://yarnpkg.com/lang/zh-hans/docs/install/ 使用国内镜像加速npm和yarn 1. npm config set registry=ht ...
- Jmeter做读取csv接口测试
最近在工作中,对jmeter实践的点滴的记录这里分享,不一定正确,仅供参考和讨论,有想法的欢迎留言.谈论. 1技巧1:从csv中获取带引号的数据详情 背景:我们从csv中获取数据,在jmeter中使用 ...
- tomcat启动不起来,不知原因,没有报错日志,控制台一闪而过 怎么办
在startup.bat文件中 编辑,在最后一行回车 加上一个词pause,暂停,然后再启动就看见控制台的错误信息啦,然后就自己解决吧
- 时间格式转换 json 转 datetime js c#
情景描述:使用C#在后台中传递时间到ajax中,因为是一个list<model>就直接用了Json 作为载体,但是在js中获得到的时间是var time='/Date(********** ...
- 【BZOJ3122】[Sdoi2013]随机数生成器 BSGS+exgcd+特判
[BZOJ3122][Sdoi2013]随机数生成器 Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b, ...
- 【BZOJ3944/4805】Sum/欧拉函数求和 杜教筛
[BZOJ3944]Sum Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用 ...
- Date、Calendar、DateFormat、SimpleDateFormat、Timer、TimerTask类
类 Date 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年.月.日.小时.分钟和秒值. 它也允许格式化和解析日期字符串.不过,这些函数的 API 不易于实现国际化.从 ...
- CSS3 Flex布局(项目)
一.order属性 order属性定义项目的排列顺序.数值越小,排列越靠前,默认为0. 二.flex-grow属性 flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大. ...