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 ...
随机推荐
- 我的消灭复杂password之行
近期几天.网易一直提示邮箱账号异常.特意去查看了一下,发现须要改动password.可是经常使用的password又不让反复使用.于是无奈之下.就想办法消灭这些复杂password,由于实在是太难(g ...
- php 打印debug日志
A lesser known trick is that mod_php maps stderr to the Apache log. And, there is a stream for that, ...
- 第二章----python函数
第一节:调用函数 1.函数是什么? 函数是组织好的,可以重复利用的. 2.为什么要用到函数? 提高应用的模块性,提高重复利用率.指的是:多个文件中可能都要用到该函数,直接拿来调用就行,不用在重复写一个 ...
- Laragon集成开发环境+配置Xdebug+postman运行Xdebug
[ Laravel 5.5 文档 ] 快速入门 —— 使用 Laragon 在 Windows 中搭建 Laravel 开发环境:http://laravelacademy.org/post/7754 ...
- Android UI开发第二十七篇——实现左右划出菜单
年前就想写左右滑动菜单,苦于没有时间,一直拖到现在,这篇代码实现参考了网上流行的SlidingMenu,使用的FrameLayout布局,不是扩展的HorizontalScrollView. 程序中自 ...
- JSON查看小工具
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Langu ...
- 巨蟒python全栈开发django4:url反向解析图解&&模板渲染
第一部分: 1.(1)知识点回顾: django回顾: ()下载安装 输入网址,a,form表单get post,爬虫 (请求)==>django项目服务端的url(r"index/& ...
- 在使用NavigationController情况下的布局的Y轴的起始位置
在有的时候,当一个ViewController被push进一个NavigationController的时候,view上会有一个高度为64的NavigationBar(除非主动隐藏了Navigatio ...
- TypeError: save() missing 1 required positional argument: 'self'
RT,在创建模型对象的时候,提示TypeError: save() missing 1 required positional argument: 'self' 解决办法:在创建模型对象的时候需要加上 ...
- Java输入输出重定向代码
try { BufferedInputStream in = new BufferedInputStream(new FileInputStream("input.txt")) ...