一、iOS應(yīng)用數(shù)據(jù)存儲(chǔ)的常用方式:
1> XML屬性列表(plist)歸檔
2> Preference(偏好設(shè)置)
3> NSKeyedArchiver歸檔(NSCoding)
4> SQLite3
5> Core Data
二浑吟、應(yīng)用沙盒
1旱幼、每個(gè)iOS應(yīng)用都有自己的應(yīng)用沙盒(應(yīng)用沙盒就是文件系統(tǒng)目錄)查描,與其他文件系統(tǒng)隔離。應(yīng)用必須待在自己的沙盒里,其他應(yīng)用不能訪問該沙盒
2冬三、應(yīng)用沙盒的文件系統(tǒng)目錄匀油,如下圖所示(假設(shè)應(yīng)用的名稱叫Layer)
3、模擬器應(yīng)用的沙盒根路徑在:(apple是用戶名勾笆,8.0是模擬器版本)
/User/apple/Library/Application Soupport/iPhone Simulator/8.0/Applications
三敌蚜、應(yīng)用沙盒結(jié)構(gòu)分析:
(1)應(yīng)用程序包:(上圖中的Layer)包含了所有的資源文件和可執(zhí)行文件。
(2)Documents:保存應(yīng)用運(yùn)行時(shí)生成的?需要持久化的數(shù)據(jù)?匠襟,iTunes同步設(shè)備時(shí)?會(huì)備份?該目錄钝侠。例如:游戲應(yīng)用可將游戲存檔保存在該目錄。
(3)tmp:保存應(yīng)用運(yùn)行時(shí)所需的?臨時(shí)數(shù)據(jù)?酸舍,使用完畢后再將相應(yīng)的文件從該目錄刪除。應(yīng)用沒有運(yùn)行時(shí)里初,系統(tǒng)也可能會(huì)清除該目錄下的文件啃勉。iTunes同步設(shè)備時(shí)?不會(huì)備份?該目錄。
(4)Library:下面有兩個(gè)文件夾(Caches 双妨、Preference)
Library / Caches:保存應(yīng)用運(yùn)行時(shí)生成的?需要持久化的數(shù)據(jù)淮阐,iTunes同步設(shè)備時(shí)?不會(huì)備份?該目錄。一般存儲(chǔ)體積大刁品、不需要備份的非重要數(shù)據(jù)泣特。
Library / Preference:保存應(yīng)用的所有?偏好設(shè)置,iOS的Settings(設(shè)置)應(yīng)用會(huì)在該目錄中查找應(yīng)用的設(shè)置信息挑随。iTunes同步設(shè)備時(shí)?會(huì)備份?該目錄状您。
四、應(yīng)用沙盒目錄的常見獲取方式
1兜挨、沙盒根目錄:NSString*home =NSHomeDirectory();
2膏孟、Documents:(2種方式)
2.1 利用沙盒根目錄拼接”Documents”字符串
NSString *home = NSHomeDirectory();
NSString *documents = [home stringByAppendingPathComponent:@"Documents"];
//不建議采用,因?yàn)樾掳姹镜牟僮飨到y(tǒng)可能會(huì)修改目錄名
2.2 利用NSSearchPathForDirectoriesInDomains函數(shù)
// NSUserDomainMask 代表從用戶文件夾下找
// YES 代表展開路徑中的波浪字符“~”
NSArray*array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, NO);
// 在iOS中拌汇,只有一個(gè)目錄跟傳入的參數(shù)匹配柒桑,所以這個(gè)集合里面只有一個(gè)元素
NSString *documents = [array objectAtIndex:0];
3、tmp:NSString*tmp = NSTemporaryDirectory();
4噪舀、Library/Caches:(跟Documents類似的2種方法)魁淳;
4-1、利用沙盒根目錄拼接”Caches”字符串
4-2与倡、利用NSSearchPathForDirectoriesInDomains函數(shù)(將函數(shù)的第2個(gè)參數(shù)改為:NSCachesDirectory即可)界逛;
5、Library/Preference:通過NSUserDefaults類存取該目錄下的設(shè)置信息蒸走。
五仇奶、屬性列表:Plist文件 ---- 存儲(chǔ)數(shù)據(jù)
1、屬性列表是一種XML格式的文件,拓展名為plist
2该溯、如果對(duì)象是NSString岛抄、NSDictionary、NSArray狈茉、NSData夫椭、NSNumber等類型,就可以使用writeToFile:atomically:方法直接將對(duì)象寫到屬性列表文件中
5-1氯庆、屬性列表 --- 歸檔NSDictionary
a蹭秋、將一個(gè)NSDictionary對(duì)象歸檔到一個(gè)plist屬性列表中
// ?將數(shù)據(jù)封裝成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"母雞" forKey:@"name"];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// ?將字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
b、成功寫入到Documents目錄下:如圖 -- b
b-1堤撵、用文本編輯器打開仁讨,文件內(nèi)容為:如圖 ?b -- 1
b-2、用xcode打開屬性文件(Plist文件打開):如圖? b -- 2
5-2实昨、屬性列表 --- 恢復(fù)NSDictionary
a洞豁、讀取屬性列表,恢復(fù)NSDictionary對(duì)象
// 讀取Documents/stu.plist的內(nèi)容荒给,實(shí)例化NSDictionary
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"name:%@", [dict objectForKey:@"name"]);
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);
打印Log如下圖5--2--a:
b丈挟、屬性列表-NSDictionary的存儲(chǔ)和讀取過程.
如圖5--2--b所示:
六、偏好設(shè)置 --- 存儲(chǔ)數(shù)據(jù)
1志电、很多iOS應(yīng)用都支持偏好設(shè)置曙咽,比如保存用戶名、密碼挑辆、字體大小等設(shè)置例朱,iOS提供了一套標(biāo)準(zhǔn)的解決方案來為應(yīng)用加入偏好設(shè)置功能.
2、每個(gè)應(yīng)用都有個(gè)NSUserDefaults實(shí)例之拨,通過它來存取偏好設(shè)置.
3茉继、比如 : 保存用戶名、字體大小蚀乔、是否自動(dòng)登錄.
4烁竭、創(chuàng)建 NSUserDefaults
4-1、寫入數(shù)據(jù):圖3-1吉挣、 圖3-2
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"itcast" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];
4-2派撕、讀取上次保存的設(shè)置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
4-3、注意:UserDefaults設(shè)置數(shù)據(jù)時(shí)睬魂,不是立即寫入终吼,而是根據(jù)時(shí)間戳定時(shí)地把緩存中的數(shù)據(jù)寫入本地磁盤。所以調(diào)用了set方法之后數(shù)據(jù)有可能還沒有寫入磁盤應(yīng)用程序就終止了氯哮。出現(xiàn)以上問題洼专,可以通過調(diào)用synchornize方法強(qiáng)制寫入
[defaults synchornize];
七、NSKeyedArchiver
1.如果對(duì)象是NSString砌创、NSDictionary、NSArray良姆、NSData、NSNumber等類型幔戏,可以直接用NSKeyedArchiver進(jìn)行歸檔和恢復(fù)玛追。
2.不是所有的對(duì)象都可以直接用這種方法進(jìn)行歸檔,只有遵守了NSCoding協(xié)議的對(duì)象才可以闲延。
3.NSCoding協(xié)議有2個(gè)方法:
a痊剖、encodeWithCoder:
每次歸檔對(duì)象時(shí),都會(huì)調(diào)用這個(gè)方法垒玲。一般在這個(gè)方法里面指定如何歸檔對(duì)象中的每個(gè)實(shí)例變量陆馁,可以使用encodeObject:forKey:方法歸檔實(shí)例變量。
b侍匙、initWithCoder:
每次從文件中恢復(fù)(解碼)對(duì)象時(shí)氮惯,都會(huì)調(diào)用這個(gè)方法。一般在這個(gè)方法里面指定如何解碼文件中的數(shù)據(jù)為對(duì)象的實(shí)例變量想暗,可以使用decodeObject:forKey方法解碼實(shí)例變量。
7.1帘不、NSKeyedArchiver ?--- ?歸檔NSArray
? 歸檔一個(gè) NSArray 對(duì)象到 Documents/array.archive
NSArray *array = [NSArray arrayWithObjects:@”a”,@”b”,nil];
[NSKeyedArchiver archiveRootObject: array toFile:path];
? 歸檔成功:如圖 7-1
? 恢復(fù)(解碼)NSArray對(duì)象.如圖 7-2
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
7.2 NSKeyedArchiver ?--- ?歸檔Person對(duì)象
Person.h ? 文件
@interface?Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign)
float height;
@end
Person.m? 文件
@implementation Person
- (void)encodeWithCoder:(NSCoder *)encoder {
? ? ? ? ? [encoderencodeObject:self.nameforKey:@"name"];
? ? ? ? ? [encoderencodeInt:self.ageforKey:@"age"];
? ? ? ? ? [encoderencodeFloat:self.heightforKey:@"height"];
}
- (id)initWithCoder:(NSCoder *)decoder {
? ? ? ? ? self.name= [decoderdecodeObjectForKey:@"name"];
? ? ? ? ? self.age= [decoderdecodeIntForKey:@"age"];
? ? ? ? ? self.height= [decoderdecodeFloatForKey:@"height"];
? ? ? ? ? return self;
}
- (void)dealloc {
? ? ? ? ? ? [superdealloc];
? ? ? ? ? ? [_name release];
}
@end
NSKeyedArchiver-歸檔Person對(duì)象(編碼和解碼)
歸檔(編碼)
Person *person = [[[Person alloc] init] autorelease];
person.name = ?@"MJ";
person.age = 27;
person.height = 1.83f;
[NSKeyedArchiver archiveRootObject:person toFile:path];
恢復(fù)(解碼)
Person *person = ?[NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSKeyedArchiver-歸檔對(duì)象的注意
1.如果父類也遵守了NSCoding協(xié)議说莫,請(qǐng)注意:
1-1、應(yīng)該在encodeWithCoder:方法中加上一句
? ? ? ? ? [super encodeWithCode:encode];
確保繼承的實(shí)例變量也能被編碼寞焙,即也能被歸檔储狭。
1-2、應(yīng)該在initWithCoder:方法中加上一句
? ? ? ? ? self = [super initWithCoder:decoder];
確保繼承的實(shí)例變量也能被解碼捣郊,即也能被恢復(fù)辽狈。
7.3 NSData 圖 7-3
1、使用archiveRootObject:toFile:方法可以將一個(gè)對(duì)象直接寫入到一個(gè)文件中呛牲,但有時(shí)候可能想將多個(gè)對(duì)象寫入到同一個(gè)文件中刮萌,那么就要使用NSData來進(jìn)行歸檔對(duì)象。
2娘扩、NSData可以為一些數(shù)據(jù)提供臨時(shí)存儲(chǔ)空間着茸,以便隨后寫入文件,或者存放從磁盤讀取的文件內(nèi)容琐旁′汤可以使用[NSMutableData data]創(chuàng)建可變數(shù)據(jù)空間。
7.3-1 NSData-歸檔2個(gè)Person對(duì)象到同一文件中
歸檔(編碼)
//新建一塊可變數(shù)據(jù)區(qū)
NSMutableData *data = [NSMutableData data];
//將數(shù)據(jù)區(qū)連接到一個(gè)NSKeyedArchiver對(duì)象
NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:data] autorelease];
//開始存檔對(duì)象灰殴,存檔的數(shù)據(jù)都會(huì)存儲(chǔ)到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
//存檔完畢(一定要調(diào)用這個(gè)方法)
[archiver finishEncoding];
//將存檔的數(shù)據(jù)寫入文件
[data writeToFile:path atomically:YES];
7.3-2 NSData-從同一文件中恢復(fù)2個(gè)Person對(duì)象
恢復(fù)(解碼)
// 從文件中讀取數(shù)據(jù)
NSData *data = [NSData dataWithContentsOfFile:path];
// 根據(jù)數(shù)據(jù)敬特,解析成一個(gè)NSKeyedUnarchiver對(duì)象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢復(fù)完畢
[unarchiver finishDecoding];
7.4 利用歸檔實(shí)現(xiàn)深復(fù)制 。圖7-4
比如對(duì)一個(gè)Person對(duì)象進(jìn)行深復(fù)制
//臨時(shí)存儲(chǔ)person1的數(shù)據(jù)
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
//解析data,生成一個(gè)新的Person對(duì)象
Student*person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 分別打印內(nèi)存地址
NSLog(@"person1:0x%x",person1); // person1:0x7177a60
NSLog(@"person2:0x%x",person2); // person2:0x7177cf0
八伟阔、SQLite
1辣之、什么是SQLite?
SQLite是一款輕型的嵌入式數(shù)據(jù)庫(kù)
它占用資源非常的低减俏,在嵌入式設(shè)備中召烂,可能只需要幾百K的內(nèi)存就夠了
它的處理速度比Mysql、PostgreSQL這兩款著名的數(shù)據(jù)庫(kù)都還快
2娃承、什么是數(shù)據(jù)庫(kù)奏夫?
數(shù)據(jù)庫(kù)(Database)是按照數(shù)據(jù)結(jié)構(gòu)來組織、存儲(chǔ)和管理數(shù)據(jù)的倉(cāng)庫(kù)
數(shù)據(jù)庫(kù)可以分為2大種類
??關(guān)系型數(shù)據(jù)庫(kù)( 主流? )
??對(duì)象型數(shù)據(jù)庫(kù)
3历筝、常用關(guān)系型數(shù)據(jù)庫(kù)
PC端:Oracle酗昼、MySQL、SQLServer梳猪、Access麻削、DB2、Sybase
嵌入式\移動(dòng)客戶端:SQLite
4春弥、如何存儲(chǔ)數(shù)據(jù)呛哟?
4.1、數(shù)據(jù)庫(kù)是如何存儲(chǔ)數(shù)據(jù)的匿沛?
p.數(shù)據(jù)庫(kù)的存儲(chǔ)結(jié)構(gòu)和excel很像扫责,以表(table)為單位
4.2、數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù)的步驟:
p1.新建數(shù)據(jù)庫(kù)文件
p2.新建一張表(table)
p3.添加多個(gè)字段(column逃呼,列鳖孤,屬性)
p4.添加多行記錄(row,每行存放多個(gè)字段對(duì)應(yīng)的值)
5抡笼、Navicat:數(shù)據(jù)庫(kù)管理軟件
1苏揣、Navicat是一款著名的數(shù)據(jù)庫(kù)管理軟件,支持大部分主流數(shù)據(jù)庫(kù)(包括SQLite)
2推姻、利用Navicat建立數(shù)據(jù)庫(kù)連接:如圖8-1
3平匈、建表:如圖8-2
2.1、Navicat建立數(shù)據(jù)庫(kù)連接如圖8-1
2.2拾碌、建表如圖8-2
3.3吐葱、查看DDL 如圖8-3
4.4、執(zhí)行SQL語句 如圖8-4
8-1校翔、SQL語句
1弟跑、如何在程序運(yùn)行過程中操作數(shù)據(jù)庫(kù)中的數(shù)據(jù)?
1> 那得先學(xué)會(huì)使用SQL語句防症。
2孟辑、什么是SQL哎甲?
1> SQL(structuredquerylanguage):結(jié)構(gòu)化查詢語言。
2> SQL是一種對(duì)關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行?定義?和?操作?的語言饲嗽。
3> SQL語言簡(jiǎn)潔炭玫,語法簡(jiǎn)單,好學(xué)好用
3貌虾、什么是SQL語句吞加?
1> 使用SQL語言編寫出來的句子\代碼,就是SQL語句尽狠。
2> 在程序運(yùn)行過程中衔憨,要想操作(增刪改查,CRUD)數(shù)據(jù)庫(kù)中的數(shù)據(jù)袄膏,必須使用SQL語句践图。
4、SQL語句的特點(diǎn)
1> 不區(qū)分大小寫(比如數(shù)據(jù)庫(kù)認(rèn)為user和UsEr是一樣的)
2> 每條語句都必須以分號(hào);結(jié)尾
5沉馆、SQL中的常用關(guān)鍵字有
select码党、insert、update斥黑、delete揖盘、from、create锌奴、where扣讼、desc、order缨叫、by、group荔燎、table耻姥、alter、view有咨、index等等;
6琐簇、數(shù)據(jù)庫(kù)中不可以使用關(guān)鍵字來命名表、字段;
8-2座享、SQL語句的種類
1婉商、數(shù)據(jù)定義語句(DDL:DataDefinitionLanguage)
1.1> 包括create和drop、alter等操作.
1.2> 在數(shù)據(jù)庫(kù)中?創(chuàng)建新表?或?刪除表(crea tetable?或?drop table).
2渣叛、數(shù)據(jù)操作語句(DML:Data Manipulation Language)
2.1> 包括 insert丈秩、update、delete等操作.
2.2> 上面的3種操作分別用于?添加淳衙、修改蘑秽、刪除?表中的數(shù)據(jù).
3饺著、數(shù)據(jù)查詢語句(DQL:Data Query Language)
3.1> 可以用于查詢獲得表中的數(shù)據(jù).
3.2> 關(guān)鍵字select是DQL(也是所有SQL)用得最多的操作.
3.3> 其他DQL常用的關(guān)鍵字有where,orderby肠牲,groupby 和 having.
學(xué)習(xí)SQL資料:http://www.phpstudy.net
8-3幼衰、DDL語句(主要是對(duì)表的操作)
1、創(chuàng)建表
1> 格式:create table 表名 (字段名1 字段類型1, 字段名2 字段類型2, …) ;
2>示例:create table t_student (id integer, name text, age inetger, score real) ;
3>經(jīng)驗(yàn):
A缀雳、實(shí)際上SQLite是無類型的
A1渡嚣、就算聲明為integer類型,還是能存儲(chǔ)字符串文本(主鍵除外)肥印。
A2识椰、建表時(shí)聲明啥類型或者不聲明類型都可以,也就意味著創(chuàng)表語句可以這么寫:create table t_student(name, age);
A3竖独、為了保持良好的編程規(guī)范裤唠、方便程序員之間的交流,編寫建表語句的時(shí)候最好加上每個(gè)字段的具體類型.
B莹痢、語句優(yōu)化
B1种蘸、創(chuàng)建表格時(shí), 最好加個(gè)表格是否已經(jīng)存在的判斷, 這個(gè)防止語句多次執(zhí)行時(shí)發(fā)生錯(cuò)誤:create table if not exists 表名 (字段名1 字段類型1, 字段名2 字段類型2, …) ;
如:create table if not exists t_student (id integer,name text,age inetger,score real);
2、刪除表
1> 格式: drop table 表名 ; \ drop table if exists 表名 ;
2>示例: drop table t_student ;\ drop table if exists t_student ;
3>語句優(yōu)化:刪除表格時(shí), 最好加個(gè)表格是否已經(jīng)存在的判斷, 這個(gè)防止語句多次執(zhí)行時(shí)發(fā)生錯(cuò)誤.\ drop table if? exists 表名 ;
如:drop table?if not exists?t_student竞膳;
3航瞭、修改表
注意: sqlite里面只能實(shí)現(xiàn)Alter Table的部分功能。不能刪除一列, 修改一個(gè)已經(jīng)存在的列名
修改表名:ALTER TABLE 舊表名 RENAME TO 新表名
新增屬性:ALTER TABLE 表名 ADD COLUMN 列名 數(shù)據(jù)類型 限定符
補(bǔ)充:字段類型
1坦辟、SQLite將數(shù)據(jù)劃分為以下幾種存儲(chǔ)類型:
integer:整型值 ? ? ? ? ? ?real:浮點(diǎn)值
text:文本字符串 ? ? ? ? ?blob:二進(jìn)制數(shù)據(jù)(比如文件)
2刊侯、實(shí)際上SQLite是無類型的
2.1 就算聲明為integer類型,還是能存儲(chǔ)字符串文本(主鍵除外)
2.2 建表時(shí)聲明啥類型或者不聲明類型都可以锉走,也就意味著創(chuàng)表語句可以這么寫:create table t_student(name, age);
3滨彻、為了保持良好的編程規(guī)范、方便程序員之間的交流挪蹭,編寫建表語句的時(shí)候最好加上每個(gè)字段的具體類型
8-4亭饵、約束
1、簡(jiǎn)單約束
1>?不能為空? not null :規(guī)定字段的值不能為null
2>?不能重復(fù)? unique :規(guī)定字段的值必須唯一
3>?默認(rèn)值? ? ?default :指定字段的默認(rèn)值
示例:create table t_student (id integer, name text not null unique, age integer not null default 1) ;
a梁厉、name字段不能為null辜羊,并且唯一。
b词顾、age字段不能為null八秃,并且默認(rèn)為1。
2肉盹、主鍵約束
2.1昔驱、添加主鍵約束的原因?
如果t_student表中就name和age兩個(gè)字段垮媒,而且有些記錄的name和age字段的值都一樣時(shí)舍悯,那么就沒法區(qū)分這些數(shù)據(jù)航棱,造成數(shù)據(jù)庫(kù)的記錄不唯一,這樣就不方便管理數(shù)據(jù)萌衬。良好的數(shù)據(jù)庫(kù)編程規(guī)范應(yīng)該要保證每條記錄的唯一性饮醇,為此,增加了主鍵約束秕豫。也就是說朴艰,每張表都必須有一個(gè)主鍵,用來標(biāo)識(shí)記錄的唯一性混移。
2.2祠墅、什么是主鍵?
1>主鍵(Primary Key,簡(jiǎn)稱PK)用來唯一地標(biāo)識(shí)某一條記錄歌径。
例如:t_student可以增加一個(gè)id字段作為主鍵毁嗦,相當(dāng)于人的身份證
2>主鍵可以是一個(gè)字段或多個(gè)字段
2.3、主鍵的設(shè)計(jì)原則?
? ? ? ? ?1>主鍵應(yīng)當(dāng)是對(duì)用戶沒有意義的回铛;
? ? ? ? ?2>永遠(yuǎn)也不要更新主鍵狗准;
? ? ? ? ?3>主鍵不應(yīng)包含動(dòng)態(tài)變化的數(shù)據(jù);
? ? ? ? ?4>主鍵應(yīng)當(dāng)由計(jì)算機(jī)自動(dòng)生成.
2.4茵肃、主鍵的聲明?
1> 在創(chuàng)表的時(shí)候用primary key聲明一個(gè)主鍵:
create table t_student (id integer primary key, name text, age integer) ;
integer類型的id作為t_student表的主鍵.
2> 主鍵字段
只要聲明為primary key腔长,就說明是一個(gè)主鍵字段
主鍵字段默認(rèn)就包含了not null 和 unique 兩個(gè)約束
3> 如果想要讓主鍵自動(dòng)增長(zhǎng)(必須是integer類型),應(yīng)該增加autoincrement
create table t_student (id integer primary key autoincrement, name text, age integer) ;
8-5验残、DML語句(主要操作表中的每一條記錄的捞附,主要是: 增、刪您没、改)
1. 插入數(shù)據(jù)(insert)
格式:insert into 表名 (字段1, 字段2, …) values (字段1的值, 字段2的值, …) ;
示例:insert into t_student (name, age) values (‘sz’,10) ;
注意:數(shù)據(jù)庫(kù)中的字符串內(nèi)容應(yīng)該用單引號(hào) ’ 括住
2. 更新數(shù)據(jù)(update)
格式:update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值, … ;
示例:update t_student set name = ‘wex’, age = 20 ;
注意:上面的示例會(huì)將t_student表中所有記錄的name都改為wex鸟召,age都改為20
3. 刪除數(shù)據(jù)(delete)
格式:delete from 表名 ;
示例:delete from t_student ;
注意:上面的示例會(huì)將t_student表中所有記錄都刪掉
8-6、條件語句
1氨鹏、如果只想更新或者刪除某些固定的記錄药版,那就必須在DML語句后加上一些條件
2、條件語句的常見格式
? ? ? where字段=某個(gè)值;//不能用兩個(gè)=
? ? ? where字段is某個(gè)值;//is相當(dāng)于=
? ? ? where字段!=某個(gè)值;
? ? ? where字段isnot某個(gè)值;//isnot相當(dāng)于!=
? ? ? where字段>某個(gè)值;
? ? ? where字段1=某個(gè)值and字段2>某個(gè)值;//and相當(dāng)于C語言中的&&
? ? ? where字段1=某個(gè)值or字段2=某個(gè)值;//or相當(dāng)于C語言中的||
條件語句練習(xí)
示例:
1喻犁、將t_student表中年齡大于10 并且 姓名不等于wex的記錄,年齡都改為 5.
? ? ? update t_student set age = 5 where age > 10 and name != ‘wex’ ;
2何缓、刪除t_student表中年齡小于等于10 或者 年齡大于30的記錄
? ? ? delete from t_student where age <= 10 or age > 30 ;
猜猜下面語句的作用肢础?
3、update t_student set score = age where name = ‘wex’ ;
? ? ? 將t_student表中名字等于wex的記錄碌廓,score字段的值 都改為 age字段的值
8-7传轰、DQL (查詢相關(guān)語句)
格式
select 字段1, 字段2, …from表名;
select *from 表名;? ? //查詢所有的字段
示例
select name, age from t_student;
select *from t_student;
select *from t_student where age>10;//條件查詢
1 、統(tǒng)計(jì)
(1)計(jì)算記錄的數(shù)量 :count(X)
格式:
select count (字段) from 表名;
select count (*) from 表名;
示例:
select count (age) from t_student;
select count (*) from t_student where score >= 60;
(2)補(bǔ)充:
計(jì)算某個(gè)字段的平均值 :avg(X)
計(jì)算某個(gè)字段的總和:sum(X)
計(jì)算某個(gè)字段的最大值:max(X)
計(jì)算某個(gè)字段的最小值:min(X)
2 谷婆、排序
(1)查詢出來的結(jié)果可以用 order by 進(jìn)行排序
select * from 表名 order by 字段;
select * from t_student order by age;? //(默認(rèn)升序)
(2)默認(rèn)是按照升序排序(由小到大)慨蛙,也可以變?yōu)榻敌颍ㄓ纱蟮叫辽聊。?/i>
select * from t_student order by age desc; //降序
select * from t_student order by age asc;? //升序(默認(rèn))
(3)也可以用多個(gè)字段進(jìn)行排序
select * from t_student order by age asc,height desc;
??先按照年齡排序(升序),年齡相等就按照身高排序(降序)
3 期贫、limit分頁(yè)? ?使用 limit 可以 精確地控制 查詢結(jié)果 的數(shù)量跟匆,比如 :每次只查詢10條數(shù)據(jù)
(1)格式:
? ?select * from 表名 limit 數(shù)值1, 數(shù)值2 ;
(2)示例:
? ?select * from t_student limit 4, 8 ;
? ?可以理解為:跳過最前面4條語句,然后取8條記錄
(3)分頁(yè):
(3.1)?limit常用來做分頁(yè)查詢通砍,比如每頁(yè)固定顯示5條數(shù)據(jù)玛臂,那么應(yīng)該這樣取數(shù)據(jù)。
? ?第1頁(yè):limit 0, 5 ?封孙; 第2頁(yè):limit 5, 5? 迹冤; 第3頁(yè):limit 10, 5 ······ 第n頁(yè):limit 5*(n-1), 5
(3.2)特殊案例
? ?select * from t_student limit 7 ;
? ?相當(dāng)于select * from t_student limit 0, 7 ;
? ?表示取最前面的7條記錄
8-8、多表查詢
1虎忌、多表查詢:select 字段1, 字段2, … from 表名1, 表名2 ;
2 泡徙、起別名
( 1 )格式(字段 和 表 都可以 起別名)
//select 字段1 別名,字段2 別名,…from 表名? 別名;
//select 字段1 別名,字段2 as 別名,…from 表名 as? 別名;
//select 別名.字段1, 別名.字段2, …from 表名? 別名;select
別名1.字段1 as 字段別名1,
別名2.字段2 as 字段別名2,
…
from
表名1 as 別名1,
表名2 as 別名2 ;
可以給表或者字段單獨(dú)起別名,as 可以省略
( 2 )示例
2.1. select name myname, age myage from t_student;
??給name起個(gè)叫做myname的別名膜蠢,給age起個(gè)叫做myage的別名
2.2. select s.name,s.age from t_student s;
??給t_student表起個(gè)別名叫做 ‘s’ 利用 s 來引用表中的字段堪藐。
3、表連接查詢
select 字段1, 字段2, … from 表名1, 表名2? where 表名1.id = 表名2.id;
4狡蝶、外鍵
如果表A的主關(guān)鍵字是表B中的字段,則該字段(也就是表A的主關(guān)鍵字)稱為表B的外鍵
保持?jǐn)?shù)據(jù)一致性庶橱,完整性,主要目的是控制存儲(chǔ)在外鍵表中的數(shù)據(jù)贪惹。 使兩張表形成關(guān)聯(lián)苏章,外鍵只能引用外表中的列的值或使用空值。
九奏瞬、FMDB
一枫绅、FMDB簡(jiǎn)介
1.什么是FMDB
1.1、FMDB是iOS平臺(tái)的SQLite數(shù)據(jù)庫(kù)框架
1.2硼端、FMDB以O(shè)C的方式封裝了SQLite的C語言API
2.FMDB的優(yōu)點(diǎn)
2.1并淋、使用起來更加面向?qū)ο螅∪チ撕芏嗦闊┱渥颉⑷哂嗟腃語言代碼
2.2县耽、對(duì)比蘋果自帶的CoreData框架,更加輕量級(jí)和靈活
2.3镣典、提供了多線程安全的數(shù)據(jù)庫(kù)操作方法兔毙,有效地防止數(shù)據(jù)混亂
3.FMDB的github地址
二、FMDB基本使用
2-1兄春、核心類
FMDB有三個(gè)主要的類:FMDatabase澎剥、FMResultSet、FMDatabaseQueue
1.FMDatabase
一個(gè)FMDatabase對(duì)象就代表一個(gè)單獨(dú)的SQLite數(shù)據(jù)庫(kù)
用來執(zhí)行SQL語句
2.FMResultSet
使用FMDatabase執(zhí)行查詢后的結(jié)果集
3.FMDatabaseQueue
用于在多線程中執(zhí)行多個(gè)查詢或更新赶舆,它是線程安全的
2-2哑姚、 打開數(shù)據(jù)庫(kù)
1.通過指定SQLite數(shù)據(jù)庫(kù)文件路徑來創(chuàng)建FMDatabase對(duì)象
FMDatabase *db = [FMDatabase databaseWithPath:path];
if (![db open]) {
NSLog(@"數(shù)據(jù)庫(kù)打開失敿婪埂!");
}
2.文件路徑有三種情況
1>具體文件路徑
??如果不存在會(huì)自動(dòng)創(chuàng)建
2>空字符串@""
??會(huì)在臨時(shí)目錄創(chuàng)建一個(gè)空的數(shù)據(jù)庫(kù)
??當(dāng)FMDatabase連接關(guān)閉時(shí)叙量,數(shù)據(jù)庫(kù)文件也被刪除
3>nil
??會(huì)創(chuàng)建一個(gè)內(nèi)存中臨時(shí)數(shù)據(jù)庫(kù)倡蝙,當(dāng)FMDatabase連接關(guān)閉時(shí),數(shù)據(jù)庫(kù)會(huì)被銷毀
2-3宛乃、執(zhí)行更新
1> 在FMDB中悠咱,除查詢以外的所有操作,都稱為“更新”
create征炼、drop析既、insert、update谆奥、delete等
2> 使用executeUpdate:方法執(zhí)行更新
- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format,
- (BOOL)executeUpdate:(NSString*)sqlwithArgumentsInArray:(NSArray*)arguments
3> 示例
[db executeUpdate:@"UPDATE t_student SET age = ? WHERE name = ?;", @20, @"Jack"]
2-3眼坏、執(zhí)行查詢
1> 查詢方法
- (FMResultSet*)executeQuery:(NSString*)sql, ...
- (FMResultSet*)executeQueryWithFormat:(NSString*)format,
- (FMResultSet*)executeQuery:(NSString*)sqlwithArgumentsInArray:(NSArray*)arguments
2> 示例
//查詢數(shù)據(jù)
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"];
// 遍歷結(jié)果集
while ([rs next]) {
NSString*name = [rsstringForColumn:@"name"];
int age = [rsintForColumn:@"age"];
double score = [rsdoubleForColumn:@"score"];
}
FMDatabaseQueue
1.FMDatabase這個(gè)類是線程不安全的,如果在多個(gè)線程中同時(shí)使用一個(gè)FMDatabase實(shí)例酸些,會(huì)造成數(shù)據(jù)混亂等問題
2.為了保證線程安全宰译,F(xiàn)MDB提供方便快捷的FMDatabaseQueue類
3.FMDatabaseQueue的創(chuàng)建
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
4.簡(jiǎn)單使用
[queue inDatabase:^(FMDatabase *db) {
? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Jack"];
? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Rose"];
? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Jim"];
? ? ? FMResultSet *rs = [dbexecuteQuery:@"select* fromt_student"];
? ? ? while([rs next]) {
? ? ? ? ? ? ? ? // …
? ? ? }
}];
5.使用事務(wù)
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
? ? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Jack"];
? ? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Rose"];
? ? ? ? [dbexecuteUpdate:@"INSERT INTOt_student(name) VALUES (?)",@"Jim"];
? ? ? ? FMResultSet*rs= [dbexecuteQuery:@"select * fromt_student"];
? ? ? ? while([rsnext]) {
? ? ? ? // …
? ? ? ? }
}];
6.事務(wù)回滾
*rollback = YES;