数据持久化
1. 什么是数据持久化技术
NSString *str = @“hello world”; —>内存
实际上就是将数据存储到硬盘上,针对于iOS应用程序是存储到沙盒中。
2. iOS中有五种数据持久化技术:
# NSUserDefault (掌握)
# Property List —> plist 属性列表 (掌握)
NSString *str = @“hello world”; —>内存
实际上就是将数据存储到硬盘上,针对于iOS应用程序是存储到沙盒中。
2. iOS中有五种数据持久化技术:
# NSUserDefault (掌握)
# Property List —> plist 属性列表 (掌握)
# Archieving 归档技术 (理解)
# SQLite3 (掌握)
#Core Data
3. NSUserDefault介绍
3.1 是系统提供的自定义的类,可以随时在需要使用的地方声明对象,并随时需要的时候取出对象
3.2 支持的对象类型:NSString, NSNumber, NSData, NSArray, NSDictionary, BOOL, NSInteger, NSFloat;
3.3 不支持自定义对象类型
4. NSUserDefault特性
4.1 往NSUserDefault添加数据后,它就变成了一个全局的变量,即在整个app中可读、写NSUserDefault中的数据
4.2 可重复读/写:针对于同一个关键字对应的对象,可以重复写。
3.1 是系统提供的自定义的类,可以随时在需要使用的地方声明对象,并随时需要的时候取出对象
3.2 支持的对象类型:NSString, NSNumber, NSData, NSArray, NSDictionary, BOOL, NSInteger, NSFloat;
3.3 不支持自定义对象类型
4. NSUserDefault特性
4.1 往NSUserDefault添加数据后,它就变成了一个全局的变量,即在整个app中可读、写NSUserDefault中的数据
4.2 可重复读/写:针对于同一个关键字对应的对象,可以重复写。
4.3 *注意:*NSUserDefault是定时往磁盘/硬盘写数据,而不是及时写入;如果需要随时写入磁盘,需要调用一个同步函数synchronize,此时会强制立即写入磁盘。
5. 到底NSUserDefault持久化之后的数据,存入哪里?? ??
5.1 猜测:/Documents /Library
#import
"ViewController.h"
@interface ViewController () @property ( weak , nonatomic ) IBOutlet UITextField *nameTextField; @property ( weak , nonatomic ) IBOutlet UITextField *ageTextField; @end @implementation ViewController - ( void )viewDidLoad { [ super viewDidLoad ]; //1. 测试部分:获取沙盒的 Library 目录 NSArray *libraryPaths = NSSearchPathForDirectoriesInDomains ( NSLibraryDirectory , NSUserDomainMask , YES ); NSString *libraryPath = [libraryPaths firstObject ]; NSLog ( @"library 目录是: %@" , libraryPath); //2. 初始化数据(从第四步保存的数据中,读取它,并显示) [ self initDataByUserDefault ]; //3. 在用户将后台程序移除后,需要知道针对这个动作的触发时间/方法(通知) [[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (applicationWillDidEnterBackground:) name : UIApplicationDidEnterBackgroundNotification object :[ UIApplication sharedApplication ]]; } -( void )initDataByUserDefault { // 获取全局的 NSUserDefault 对象 NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults ]; // 使用 defaults 对象来获取保存的数据 NSString *nameStr = [defaults objectForKey : @"name" ]; NSString *ageStr = [defaults objectForKey : @"age" ]; // 将上步获取的数据,赋值给 nameTextField if (nameStr) { self . nameTextField . text = nameStr; } if (ageStr) { self . ageTextField . text = ageStr; } } - ( void )applicationWillDidEnterBackground:( NSNotification *)notification { NSLog ( @" 程序开始进入后台 ." ); //4. 在触发方法中去保存你要保存的数据 NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults ]; // 使用 defaults 来保存用户数据的名字 / 年龄文本 [defaults setObject : self . nameTextField . text forKey : @"name" ]; [defaults setObject : self . ageTextField . text forKey : @"age" ]; // 强制将用户输入的名字和年龄数据保存到硬盘中 [defaults synchronize ]; } |
属性列表 Property List(plist)持久化技术
1. 简介:属性列表是一种xml格式的文件,扩展名.plist;
2. 特性:plist文件是以 key-value的形式来保存数据
3. 支持类型:NSString, NSDictionary, NSArray, NSData, NSNumber等基本类型
4. 如何创建plist属性文件
4.1 直接使用xcode创建
4.2 使用代码来创建:可以将NSArray (NSMutableArray), NSDictionary(NSMutableDictionary)类型的数据直接写入plist文件中
5. 样例:将NSArray类型的数据写入plist文件
1. 简介:属性列表是一种xml格式的文件,扩展名.plist;
2. 特性:plist文件是以 key-value的形式来保存数据
3. 支持类型:NSString, NSDictionary, NSArray, NSData, NSNumber等基本类型
4. 如何创建plist属性文件
4.1 直接使用xcode创建
4.2 使用代码来创建:可以将NSArray (NSMutableArray), NSDictionary(NSMutableDictionary)类型的数据直接写入plist文件中
5. 样例:将NSArray类型的数据写入plist文件
6. 作业:将NSDictionary类型的数据写入plist文件
#import "ViewController.h" @interface ViewController () @property ( weak , nonatomic ) IBOutlet UITextField *nameTextFiled; @property ( weak , nonatomic ) IBOutlet UITextField *ageTextFiled; @property ( strong , nonatomic ) NSString *plistFilePath; @end @implementation ViewController - ( void )viewDidLoad { [ super viewDidLoad ]; // 初始化数据 [ self initDataByPlist ]; // 发送通知 [[ NSNotificationCenter defaultCenter ] addObserver : self selector : @selector (appDidEnterBackground) name : UIApplicationDidEnterBackgroundNotification object :[ UIApplication sharedApplication ]]; // Do any additional setup after loading the view, typically from a nib. } -( void )appDidEnterBackground { NSLog ( @" 程序进入后台 " ); //3. 在通知的触发函数中,保存数据 // 获取用户输入的用户名和年龄 NSString *name = self . nameTextFiled . text ; NSString *age = self . ageTextFiled . text ; NSArray *array = [ NSArray arrayWithObjects :name,age, nil ]; // 将数组 array 写入 plist 文件中 [array writeToFile : self . plistFilePath atomically : YES ]; } -( void )initDataByPlist { // 判定 plist 文件是否存在 if ([[ NSFileManager defaultManager ] fileExistsAtPath : self . plistFilePath ]) { // 从 plist 文件中读取 NSArray 数据 NSArray *dataArray = [ NSArray arrayWithContentsOfFile : self . plistFilePath ]; // 显示内容 self . nameTextFiled . text = dataArray[ 0 ]; self . ageTextFiled . text = dataArray[ 1 ]; } }
@end
|
归档/解档(Archiving)
归档:对象—> 文件;解档:文件—->对象
1. Archiving:不仅可以保存基本类型,还可以保存自定义的类型;在iOS中,对对象的保存的过程,叫做归档/解档(序列化)
2. 步骤
2.1 针对自定义类型(自定义类):
2.1.1 遵循NSCoding协议
2.1.2 实现NSCoding协议中定义的所有required的方法
2.2 针对调用“归档”的对象:
2.2.1 准备一个缓冲区
2.2.2 创建NSKeyArchiving对象,并和上面的缓冲区进行绑定
2.2.3 将需要保存的数据进行编码
2.2.4 将编码完的数据进行归档(写入一个归档文件中)
2.3 针对调用“解档”的对象:
2.3.1 准备一个缓冲区
2.3.2 创建NSKeyArchiving对象,并和缓冲区绑定
2.3.3 对归档的数据进行解码
归档:对象—> 文件;解档:文件—->对象
1. Archiving:不仅可以保存基本类型,还可以保存自定义的类型;在iOS中,对对象的保存的过程,叫做归档/解档(序列化)
2. 步骤
2.1 针对自定义类型(自定义类):
2.1.1 遵循NSCoding协议
2.1.2 实现NSCoding协议中定义的所有required的方法
2.2 针对调用“归档”的对象:
2.2.1 准备一个缓冲区
2.2.2 创建NSKeyArchiving对象,并和上面的缓冲区进行绑定
2.2.3 将需要保存的数据进行编码
2.2.4 将编码完的数据进行归档(写入一个归档文件中)
2.3 针对调用“解档”的对象:
2.3.1 准备一个缓冲区
2.3.2 创建NSKeyArchiving对象,并和缓冲区绑定
2.3.3 对归档的数据进行解码
2.3.4 开始解档操作
Person.h
#import
<Foundation/Foundation.h>
@interface Person : NSObject < NSCopying > @property ( strong , nonatomic ) NSString *name; @property ( strong , nonatomic ) NSString *age; -( instancetype )initWithName:( NSString *)name withAge:( NSString *)age;
@end
|
Person.m
#import
"Person.h"
@implementation Person -( instancetype )initWithName:( NSString *)name withAge:( NSString *)age { if ( self = [ super init ]) { self . name = name; self . age = age; } return self ; } // 写入数据 - ( void )encodeWithCoder:( NSCoder *)aCoder { NSLog ( @" 开始对数据进行编码 " ); [aCoder encodeObject : self . name forKey : @"name" ]; [aCoder encodeObject : self . age forKey : @"age" ]; } // 读取数据 - ( id )initWithCoder:( NSCoder *)aDecoder { NSLog ( @" 开始对数据进行解码 " ); if ( self = [ self init ]) { self . name = [aDecoder decodeObjectForKey : @"name" ]; self . age = [aDecoder decodeObjectForKey : @"age" ]; } return self ; }
@end
|
#import
"ViewController.h"
#import "Person.h" @interface ViewController () @property ( strong , nonatomic ) NSString *archivingFilePath; @end @implementation ViewController -( NSString *)archivingFilePath { if (! _archivingFilePath ) { _archivingFilePath = [[ NSHomeDirectory () stringByAppendingPathComponent : @"Documents" ] stringByAppendingPathComponent : @"archiving.bin" ]; NSLog ( @" 归档文件路径: %@" , _archivingFilePath ); } return _archivingFilePath ; } - ( void )viewDidLoad { [ super viewDidLoad ]; // 对数据进行归档 对象 ---> 文件 [ self archivingData ]; // 对数据进行解档 文件 ---> 对象 [ self deArchivingData ]; // Do any additional setup after loading the view, typically from a nib. } // 第二步 -( void )archivingData { // 准备工作:对自定义的对象初始化(实例化) Person *firstPerson = [[ Person alloc ] initWithName : @"Tonny" withAge : @"20" ]; Person *secondPerson = [[ Person alloc ] initWithName : @"Maggie" withAge : @"22" ]; //1. 创建缓冲区 NSMutableData *data = [[ NSMutableData alloc ] init ]; //2. 创建 NSKeyedArchiver 对象,并和上面的缓冲区进行绑定 NSKeyedArchiver *archiver = [[ NSKeyedArchiver alloc ] initForWritingWithMutableData :data]; //3. 将需要保存的数据进行编码 [archiver encodeObject :firstPerson forKey : @"firstPerson" ]; [archiver encodeObject :secondPerson forKey : @"secondPerson" ]; //4. 真正执行编码动作结束 [archiver finishEncoding ]; //5. 将编码完的数据进行归档(写入一个归档文件中) [data writeToFile : self . archivingFilePath atomically : YES ]; } -( void )deArchivingData { // 从归档文件中读取文件 NSData *unArchivingData = [ NSData dataWithContentsOfFile : self . archivingFilePath ]; NSKeyedUnarchiver *unArchiver = [[ NSKeyedUnarchiver alloc ] initForReadingWithData :unArchivingData]; Person *firstPerson = [unArchiver decodeObjectForKey : @"firstPerson" ]; Person *secondPerson = [unArchiver decodeObjectForKey : @"secondPerson" ]; NSLog ( @" 第一个人的名字: %@ 年龄: %@" ,firstPerson. name ,firstPerson. age ); NSLog ( @" 第二个人的名字: %@ 年龄: %@" ,secondPerson. name ,secondPerson. age ); //***** 真正执行解绑的操作 [unArchiver finishDecoding ]; }
@end
|
Oracle, DB2, SQL Server(客户端/服务器)
SQLite
1. 是一个开源的嵌入式关系数据库; sqlite大量被应用于手机,mps播放器等。
2. 特点:
2.1 实际上是由一套c语言实现的对数据库文件的读写接口。
2.2 零配置:sqlite不需要安装,不用配置
2.3 可移植性:容量小(只需要几百k的内存);容易使用
3. 在mac终端,创建数据库,表,以及进行相应的增、删、改、查(理解)。
3.1 增:在一个表中,插入一条记录(数据)
sql语言:insert into <表名> (<列名1>, <列名2>, …) values
(1, ‘tonny’, 19)
3.2 删: 在一个表中,删除一条记录(数据)
sql语言:delete from <表名> where <列名>=’’
3.3 改:在一个表中,更新一条记录(数据)
sql语言:update <表名> set <列名>=‘’where <列名>=‘’
3.4 查:在一个表中,查询一条记录(数据)
sql语言:select * from <表名>
3.5 主键:primary key (id)
insert into person (name, age) values
(‘tonny’, 19)
3.6 如何创建一个表
sql语言:create table <表名> (<列名1>, <列名2>,<列名3>,…)
create table person (id integer primary key, name text, age integer)
3.7 sqlite的支持类型
1), null
2), integer: 整型
3), real: 浮点型 (1.0;。。)
4), text: 字符串
3.8 表和数据库关系:一个数据库中可以有多个表;
表不可以单独存在
person: 表名
id name age
1 tonny 19 -》 22
2 maggie 22
3 tonny 19
4 tonny 19
3.9 在mac终端上常用的sqlite命令
创建数据库:sqlite3 <数据库名字>
查找当前的所有数据库:.databases
查看当前数据库中的所有表:.tables
3.10 什么时候使用sqlite
需要统一的管理大量的数据、存储数据
SQLite
1. 是一个开源的嵌入式关系数据库; sqlite大量被应用于手机,mps播放器等。
2. 特点:
2.1 实际上是由一套c语言实现的对数据库文件的读写接口。
2.2 零配置:sqlite不需要安装,不用配置
2.3 可移植性:容量小(只需要几百k的内存);容易使用
3. 在mac终端,创建数据库,表,以及进行相应的增、删、改、查(理解)。
3.1 增:在一个表中,插入一条记录(数据)
sql语言:insert into <表名> (<列名1>, <列名2>, …) values
(1, ‘tonny’, 19)
3.2 删: 在一个表中,删除一条记录(数据)
sql语言:delete from <表名> where <列名>=’’
3.3 改:在一个表中,更新一条记录(数据)
sql语言:update <表名> set <列名>=‘’where <列名>=‘’
3.4 查:在一个表中,查询一条记录(数据)
sql语言:select * from <表名>
3.5 主键:primary key (id)
insert into person (name, age) values
(‘tonny’, 19)
3.6 如何创建一个表
sql语言:create table <表名> (<列名1>, <列名2>,<列名3>,…)
create table person (id integer primary key, name text, age integer)
3.7 sqlite的支持类型
1), null
2), integer: 整型
3), real: 浮点型 (1.0;。。)
4), text: 字符串
3.8 表和数据库关系:一个数据库中可以有多个表;
表不可以单独存在
person: 表名
id name age
1 tonny 19 -》 22
2 maggie 22
3 tonny 19
4 tonny 19
3.9 在mac终端上常用的sqlite命令
创建数据库:sqlite3 <数据库名字>
查找当前的所有数据库:.databases
查看当前数据库中的所有表:.tables
3.10 什么时候使用sqlite
需要统一的管理大量的数据、存储数据
3.11 主页:www.sqlite.org
4. 样例:如何在iOS程序中对sqlite数据库/表进行操作
5. 步骤:
5.1 准备工作:导入libsqlite3.dylib文件
5.2 下面的步骤请查看Day02-Sqlite
#import
"ViewController.h"
#import "sqlite3.h" @interface ViewController () @end @implementation ViewController - ( void )viewDidLoad { [ super viewDidLoad ]; // 使用 sqlite 持久化来初始化数据 [ self initDataBySqlite ]; // Do any additional setup after loading the view, typically from a nib. } -( void )initDataBySqlite { //1. 获取数据库文件的路径 NSString *dbPath = [[ NSHomeDirectory () stringByAppendingPathComponent : @"Documents" ] stringByAppendingPathComponent : @"people.db" ]; NSLog ( @" 数据可的路径是: %@" ,dbPath); //2. 创建 / 打开数据库文件 sqlite3 *db = NULL ; int ret = sqlite3_open ([dbPath cStringUsingEncoding : NSUTF8StringEncoding ],&db); if (ret != SQLITE_OK ) { NSLog ( @"shujuk 创建失败,原因是: %s" , sqlite3_errmsg (db)); } //3. 创建表 const char *creatSql = "create table people(id integer primary key, name text ,age integer)" ; char *errmsg = NULL ; int execRet = sqlite3_exec (db, creatSql, NULL , NULL , &errmsg); sqlite3_exec (db, creatSql, NULL , NULL , &errmsg); if (execRet != SQLITE_OK ) { NSLog ( @" 创建 people 表失败,失败原因是 %s" ,errmsg); } // 插入数据 sql const char *insertSql = "insert into people (name,age)values('jonny',19)" ; execRet = sqlite3_exec (db, insertSql, NULL , NULL , &errmsg); if (execRet != SQLITE_OK ) { NSLog ( @" 插入数据失败,失败原因是: %s" ,errmsg); } //4. 释放资源 sqlite3_free (errmsg); //5. 关闭 sqlite 链接 sqlite3_close (db); }
@end
|