iOS開發(fā)中的數(shù)據(jù)存儲(chǔ):一(主要是理論知識(shí))

一、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

b-1堤撵、用文本編輯器打開仁讨,文件內(nèi)容為:如圖 ?b -- 1

圖? b -- 1

b-2、用xcode打開屬性文件(Plist文件打開):如圖? b -- 2

圖? 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:

圖5--2--a

b丈挟、屬性列表-NSDictionary的存儲(chǔ)和讀取過程.

如圖5--2--b所示:

圖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"];

圖3-1


圖3-2

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

圖7-1

? 恢復(fù)(解碼)NSArray對(duì)象.如圖 7-2

NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

圖7-2

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

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

圖7-4

八伟阔、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

圖8-1

2.2拾碌、建表如圖8-2

圖8-2

3.3吐葱、查看DDL 如圖8-3

圖8-3

4.4、執(zhí)行SQL語句 如圖8-4

圖8-3

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> 包括createdrop、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)鍵字selectDQL(也是所有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地址

https://github.com/ccgus/fmdb

二、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;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市魄懂,隨后出現(xiàn)的幾起案子沿侈,更是在濱河造成了極大的恐慌,老刑警劉巖市栗,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缀拭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡填帽,警方通過查閱死者的電腦和手機(jī)蛛淋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篡腌,“玉大人褐荷,你說我怎么就攤上這事∴诘浚” “怎么了叛甫?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)杨伙。 經(jīng)常有香客問我合溺,道長(zhǎng),這世上最難降的妖魔是什么缀台? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮哮奇,結(jié)果婚禮上膛腐,老公的妹妹穿的比我還像新娘睛约。我一直安慰自己,他們只是感情好哲身,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布辩涝。 她就那樣靜靜地躺著,像睡著了一般勘天。 火紅的嫁衣襯著肌膚如雪怔揩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天脯丝,我揣著相機(jī)與錄音商膊,去河邊找鬼。 笑死宠进,一個(gè)胖子當(dāng)著我的面吹牛晕拆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播材蹬,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼实幕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了堤器?” 一聲冷哼從身側(cè)響起昆庇,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闸溃,沒想到半個(gè)月后整吆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡圈暗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年掂为,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员串。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勇哗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出寸齐,到底是詐尸還是另有隱情欲诺,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布渺鹦,位于F島的核電站扰法,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏毅厚。R本人自食惡果不足惜塞颁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧祠锣,春花似錦酷窥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澡腾,卻和暖如春沸伏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背动分。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工毅糟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刺啦。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓留特,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親玛瘸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜕青,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容