在iOS開發過程中常用的本地化存儲有五種方式:
1.plist (XML屬性列表歸檔 NSArray\NSDictionary)
2.preference (偏好設置\NSUserDefaults) (本質還是通過plist來存儲數據,但是使用更加簡單,無需關注文件、文件夾路徑和名稱)
3.NSCoding (NSKeyedArchiver\NSKeyedUnarchiver) (能把任何對象都直接保存成文件的方式)
4.SQLite3 (當非常大量的數據時候纔會使用)
5.Core Data (是對SQLite3的封裝,更加面向對象,效率沒有SQLite3高)
沙盒(sandbox):每個iOS應用都有自己的應用沙盒(應用沙盒就是應用的文件夾),與其他文件系統隔離。應用必須待在自己的沙盒裏,其他應用不能訪問該沙盒
應用沙盒的文件系統目錄,如下圖所示(假設應用的名稱叫Layer)
沙盒結構分析:
應用程序包:(上圖中的Layer)包含了所有的資源文件和可執行文件
Documents:保存應用運行時生成的需要持久化的數據,iTunes同步設備時會備份該目錄。例如,遊戲應用可將遊戲存檔保存在該目錄。保存相對重要的數據。
tmp:保存應用運行時所需的臨時數據,使用完畢後再將相應的文件從該目錄刪除。應用沒有運行時,系統也可能會清除該目錄下的文件。iTunes同步設備時不會備份該目錄。保存不重要的並且大的數據。
Library/Caches:保存應用運行時生成的需要持久化的數據,iTunes同步設備時不會備份該目錄。一般存儲體積大、不需要備份的非重要數據
Library/Preference:保存應用的所有偏好設置,iOS的Settings(設置)應用會在該目錄中查找應用的設置信息。iTunes同步設備時會備份該目錄。該目錄由系統管理, 無需我們來管理。通常用來存儲一些基本的軟件配置信息, 比如記住密碼、自動登錄等。
總結: 我們平時操作數據主要使用Documents目錄。
沙盒的目錄的獲取方式:
沙盒根目錄的獲取:
NSString *home = NSHomeDirectory();
1.利用沙盒根目錄拼接”Documents“字符串:
//這種方式不建議使用,因爲如果新版本的操作系統可能會修改目錄的名稱
NSString *home = NSHomeDirectory();
NSString *documents = [home stringByAppendingPathComponent:@“Documents”];
2.利用NSSearchPathForDirectoriesInDomains函數
// NSUserDomainMask 代表從用戶文件夾下找
// YES 代表展開路徑中的波浪字符“~”
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 在iOS中,只有一個目錄跟傳入的參數匹配,所以這個集合裏面只有一個元素
NSString *documents = [array objectAtIndex:0];
常見沙盒目錄獲取方式:
tmp:NSString *tmp = NSTemporaryDirectory();
Library/Caches:(跟Documents類似的2種方法)
利用沙盒根目錄拼接”Caches”字符串
利用NSSearchPathForDirectoriesInDomains函數(將函數的第2個參數改爲:NSCachesDirectory即可)
Library/Preference:通過NSUserDefaults類存取該目錄下的設置信息
1、XML屬性列表(plist):(不能存儲基本數據類型只能存儲OC對象)
屬性列表是一種 xml格式的文件,拓展名爲plist,如果對象是(必須是OC對象,不能存儲基本數據類型)NSString、NSDictionary/NSArray、NSData 、NSNumber等類型,就可以使用writeToFile:atomically:方法直接將對象寫到屬性列表文件中,然後用dictionaryWithContentsOfFile讀取數據。
示例代碼如下:
//保存
- (IBAction)save {
//1.獲取沙盒根路徑
NSString *home = NSHomeDirectory();
//2.document路徑
NSString *docPath = [home stringByAppendingPathComponent:@"Documents"];
//3.新建數據 數據一般只能存儲oc對象 字典也可以
NSArray *data = @[@"jack",@"mack",@15];
//4.寫數據
NSString *filePath = [docPath stringByAppendingPathComponent:@"data.plist"];
[data writeToFile:filePath atomically:YES];
}
//讀取
- (IBAction)read {
//1.獲取沙盒根路徑
NSString *home = NSHomeDirectory();
//2.document路徑
NSString *docPath = [home stringByAppendingPathComponent:@"Documents"];
//3.文件路徑
NSString *filePath = [docPath stringByAppendingPathComponent:@"data.plist"];
//4.讀取數據
NSArray *data = [NSArray arrayWithContentsOfFile:filePath];
NSLog(@"%@",data);
}
//將一個NSDictionary對象歸檔到一個plist屬性列表中
// 將數據封裝成字典
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];
//讀取屬性列表,恢復NSDictionary對象
// 讀取Documents/stu.plist的內容,實例化NSDictionary
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"name:%@", [dict objectForKey:@"name"]);
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);
2、prefrrence (偏好設置)
很多iOS應用都支持偏好設置,比如保存用戶名、密碼、字體大小等設置,iOS提供了一套標準的解決方案來爲應用加入偏好設置功能
每個應用都有個NSUserDefaults實例,通過它來存取偏好設置,比如,保存用戶名、字體大小、是否自動登錄等。
//存儲數據
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"itcast" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@“auto_login"];
//讀取上次保存的設置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];
[defaults synchornize];(立刻同步)
注意:UserDefaults設置數據時,不是立即寫入,而是根據時間戳定時地把緩存中的數據寫入本地磁盤。所以調用了set方法之後數據有可能還沒有寫入磁盤應用程序就終止了。出現以上問題,可以通過調用synchornize方法強制寫入
示例代碼如下:
//偏好設置數據存儲:(一般用來存儲軟件的配置,存儲在Library/Preferences中,不需要關注文件夾的路徑)
//存儲
- (IBAction)save {
//1.利用NSUserDefaults,就能直接訪問軟件的偏好設置(Library/Preferences
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//2.存儲數據
[defaults setObject:@"jack" forKey:@"name"];
[defaults setInteger:10 forKey:@"age"];
[defaults setBool:YES forKey:@"Login"];
//3.立刻同步
[defaults synchronize];
}
//讀取
- (IBAction)read {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:@"name"];
BOOL login = [defaults objectForKey:@"Login"];
NSLog(@"%@-- %d",name,login);
}
3、NSCoding (NSKeyedArchiver\NSKeyedUnarchiver)
如果對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,可以直接用NSKeyedArchiver進行歸檔和恢復。
不是所有的對象(非OC對象)都可以直接用這種方法進行歸檔,只有遵守了NSCoding協議的對象纔可以
NSCoding協議有2個方法:
encodeWithCoder:每次歸檔對象時,都會調用這個方法。一般在這個方法裏面指定如何歸檔對象中的每個實例變量,可以使用encodeObject:forKey:方法歸檔實例變量
initWithCoder:每次從文件中恢復(解碼)對象時,都會調用這個方法。一般在這個方法裏面指定如何解碼文件中的數據爲對象的實例變量,可以使用decodeObject:forKey方法解碼實例變量
示例代碼如下:
NSKeyedArchiver數據存儲,不僅可以用來存儲OC對象,也可以用來存儲非OC對象,以一個Person對象爲例:(想歸檔某個對象,這個對象一定要遵守NSCoding這個協議)
#import <Foundation/Foundation.h>
@interface TWPerson : NSObject <NSCoding>
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) int age;
@property (nonatomic,assign) double height;
@end
@implementation TWPerson
//將對象歸檔的時候調用(將對象寫入文件之前調用)
//在這個方法裏說清楚:1.哪些屬性需要存儲 2.怎樣存儲這些屬性
-(void)encodeWithCoder:(NSCoder *)enCoder
{
//將_name屬性進行編碼(會將_name的值存進文件)
[enCoder encodeObject:_name forKey:@"name"];
[enCoder encodeInt:_age forKey:@"age"];
[enCoder encodeDouble:_height forKey:@"height"];
}
//當從文件中解析對象時使用
//在這個方法說清楚: 1.那個屬性需要解析(讀取) 2.怎樣解析(讀取)這些屬性
- (id)initWithCoder:(NSCoder *)Decoder
{
if (self = [super init]) {
_name = [Decoder decodeObjectForKey:@"name"];
_age = [Decoder decodeIntForKey:@"age"];
_height = [Decoder decodeDoubleForKey:@"height"];
}
return self;
}
@end
//存儲數據
- (IBAction)save {
TWPerson *p = [[TWPerson alloc]init];
p.name = @"jack";
p.age = 10;
p.height = 1.82;
NSString *path = @"/Users/wtw/Desktop/person.data";
//歸檔
[NSKeyedArchiver archiveRootObject:p toFile:path];
}
//讀取數據
- (IBAction)read {
NSString *path = @"/Users/wtw/Desktop/person.data";
//讀檔(反歸檔)
TWPerson *p = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@ -- %f -- %d",p.name,p.height,p.age);
}
4、SQLite3SQLite3 是一款開源的輕型的嵌入式關係型數據庫,可移植性好、易使用、內存開銷小,SQLite3 是無類型的,可以保存任何類型的數據到任意的字段中。
數據庫存儲數據的步驟:
》新建一個數據庫(DataBase)
》新建一張表(table)
》添加多個字段(column,列,屬性)
》添加多行記錄(row,每行存放多個字段對應的值)
SQL語句的分類:
數據定義語句:(DDL :Data Definition Language)
包括create 和 drop 等操作。
在數據庫中創建新表或者刪除表(creat table 或 drop table)
數據庫操作語句: (DML : Data manipulation Language)
包括 insert 、update 、delete 等操作。
上面的3種操作分別用於添加、修改、刪除表中的數據
數據查詢語句 :(DQL : Data Query Language)
可以用於查詢獲得表中的數據
關鍵字select 是 DQL 用的最多的操作
其他DQL 常用的關鍵字有 where 、order by、group by 和 having 等。
創建表:
//創建表:
/*
創建數據表
CREATE TABLE '表名' (
'字段1' 類型(INTEGER, REAL, TEXT, BLOB)
NOT NULL 不允許爲空
PRIMARY KEY 主鍵
AUTOINCREMENT 自增長,
'字段名2' 類型,
...
)
*/
提示:可以從navicat先創建好表,複製粘貼,需要自己增加 IF NOT EXISTS
CREATE TABLE IF NOT EXISTS "T_Person" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"age" INTEGER,
"heigth" REAL
)
刪除表://刪除表
//DROP TABLE t_student;
DROP TABLE IF EXISTS t_student;
插入數據:
//插入命令:
INSERT INTO 表名
(字段名1,字段名2…..)
VALUES
(值1,值2。。。。)
//注意:值和字段一定要一致
//提示:SQLite的字段屬性,只是給程序員看的,存什麼都行
INSERT INTO t_student
(age, score, name)
VALUES
('28', 100, 'zhangsan');
更新數據:
//更新數據:
UPDATE 表名
SET
字段1 = ‘值1’ , //提示: 如果是字符串,需要使用單引號引起來
字段2 = 值2 ,...
/*更新記錄的name*/
UPDATE t_student SET name = 'zhangsan';
//注意:如果更新時沒有指定更新哪一條記錄,那麼會更新所有的數據
刪除數據:
//刪除指令:
//注意:刪除數據的時候,一定要設置條件
//如果條件不滿足,什麼也不會發生
DELETE FROM 表名
WHERE 主鍵 = 值;
//例如:
DELETE FROM t_student;
DELETE FROM t_student WHERE age < 50;
查詢數據:
//查詢指令:
/* 分頁 */
SELECT * FROM t_student
ORDER BY id ASC LIMIT 30, 10;
/* 排序 */
SELECT * FROM t_student
WHERE score > 50
ORDER BY age DESC;
SELECT * FROM t_student
WHERE score < 50
ORDER BY age ASC , score DESC;
/* 計量 */
SELECT COUNT(*)
FROM t_student
WHERE age > 50;
/* 別名 */
SELECT name as myName, age as myAge, score as myScore
FROM t_student;
SELECT name myName, age myAge, score myScore
FROM t_student;
SELECT s.name myName, s.age myAge, s.score myScore
FROM t_student s
WHERE s.age > 50;
/* 查詢 */
SELECT name, age, score FROM t_student;
SELECT * FROM t_student;
數據庫的基本使用:
@property (nonatomic, assign) sqlite3 *db;
/*
1.創建數據庫
2.創建表(指定字段)
3.操作數據庫
*/
/*
第一個參數:是告訴系統數據庫文件在什麼地方.
>如果文件不存在就會自動創建, 然後再打開
>如果數據庫存在就會自動打開
第二個參數:返回打開的數據庫對象
*/
// 1.拼接數據庫地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *sqlFile = [path stringByAppendingPathComponent:@"student.sqlite"];
// sqlite3 *db = NULL;
// 2.打開數據庫
int result = sqlite3_open(sqlFile.UTF8String, &_db);// [self db]
// 3.判斷是否打開成功
if (result == SQLITE_OK) {
NSLog(@"打開成功");
// 3.1創建表
/*
第一個參數: 需要執行SQL語句的數據庫對象
第二個參數: 需要執行的SQL語句
第三個參數: 回調函數
第四個參數: 第三個參數的參數
第五個參數: 接收錯誤信息
*/
NSString *sql = @"CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT , name TEXT, age INTEGER, score REAL);";
result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"創建表成功");
}else
{
NSLog(@"創建表失敗");
}
}else
{
NSLog(@"打開失敗");
}
- (IBAction)insertClick:(id)sender {
NSString *sql = @"INSERT INTO t_student(age, score, name) VALUES ('28', 100, 'jonathan');";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"插入成功");
}
}
- (IBAction)updateClick:(id)sender {
NSString *sql = @"UPDATE t_student SET name = 'XXX';";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"修改成功");
}
}
- (IBAction)deleteClick:(id)sender {
NSString *sql = @"DELETE FROM t_student WHERE id = 1; ";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"刪除成功");
}6
}
- (IBAction)selectClick:(id)sender {
/*
sqlite3操作中, 所有DML語句都是使用sqlite3_exec函數執行SQL語句即可,
但是如果是需要查詢數據庫, 不能使用sqlite3_exec, 因爲它並沒有返回查詢到得結果發給我們
*/
/*
NSString *sql = @"SELECT * FROM t_student;";
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
NSLog(@"查詢成功");
}
*/
// 1.準備查詢
/*
第一個參數:需要執行SQL語句的數據庫
第二個參數:需要執行的SQL語句
第三個參數: 告訴系統SQL語句的長度, 如果傳入一個小於0的數, 系統會自動計算
第四個參數:結果集, 裏面存放所有查詢到的數據(不嚴謹)
*/
NSString *sql = @"SELECT * FROM t_student;";
sqlite3_stmt *stemt = NULL;
sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stemt, NULL);
// 2.判斷有沒有查詢結果
// int result = sqlite3_step(stemt);
// if (result == SQLITE_ROW) {
while (sqlite3_step(stemt) == SQLITE_ROW) {
// NSLog(@"查詢到了數據");
// 3.取出查詢到得結果
const unsigned char *name = sqlite3_column_text(stemt, 1);
int age = sqlite3_column_int(stemt, 2);
double score = sqlite3_column_double(stemt, 3);
NSLog(@"%s %d %f", name, age, score);
}
}
數據庫的基本的封裝:
@interface SQLManager : NSObject
+ (instancetype)shareManage;
//插入新數據
- (BOOL)insertStudent:(HMStudent *)student;
//刪除數據
- (BOOL)deleteWithStudent:(HMStudent *)student;
//更新數據
- (BOOL)updateWithStudent:(HMStudent *)student;
//查詢數據
- (NSArray *)query;
@end
#import "SQLManager.h"
#import <sqlite3.h>
@implementation SQLManager
static SQLManager *_instance;
+ (instancetype)shareManage
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[SQLManager alloc] init];
});
return _instance;
}
sqlite3 *_db;
+ (void)initialize
{
// 1.拼接數據庫地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *sqlFile = [path stringByAppendingPathComponent:@"student.sqlite"];
// 2.打開數據庫
int result = sqlite3_open(sqlFile.UTF8String, &_db);// [self db]
// 3.判斷是否打開成功
if (result == SQLITE_OK) {
NSLog(@"打開成功");
// 3.1創建表
NSString *sql = @"CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT , name TEXT, age INTEGER, score REAL);";
result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
}
}
- (BOOL)insertStudent:(HMStudent *)student
{
NSString *sql = [NSString stringWithFormat: @"INSERT INTO t_student(age, score, name) VALUES (%d, %f, '%@');", student.age, student.score, student.name];
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
return YES;
}
return NO;
}
- (BOOL)deleteWithStudent:(HMStudent *)student
{
NSString *sql = [NSString stringWithFormat:@"DELETE FROM t_student WHERE id = %d;", student.ID];
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
return YES;
}
return NO;
}
- (BOOL)updateWithStudent:(HMStudent *)student
{
NSString *sql = [NSString stringWithFormat:@"UPDATE t_student SET name = '%@';", student.name];
int result = sqlite3_exec(_db, sql.UTF8String, NULL, NULL, NULL);
if (result == SQLITE_OK) {
return YES;
}
return NO;
}
- (NSArray *)query
{
NSString *sql = @"SELECT * FROM t_student;";
sqlite3_stmt *stemt = NULL;
sqlite3_prepare_v2(_db, sql.UTF8String, -1, &stemt, NULL);
// 2.判斷有沒有查詢結果
NSMutableArray *arrM = [NSMutableArray array];
while (sqlite3_step(stemt) == SQLITE_ROW) {
// 3.取出查詢到得結果
const unsigned char *name = sqlite3_column_text(stemt, 1);
int age = sqlite3_column_int(stemt, 2);
double score = sqlite3_column_double(stemt, 3);
HMStudent *stu = [[HMStudent alloc] init];
stu.name = [NSString stringWithUTF8String:name];
stu.age = age;
stu.score = score;
[arrM addObject:stu];
}
return arrM;
}
@end
FMDB的基本使用:
以OC的方式封裝了SQLite的C語言API.
優點是:
使用起來更加面向對象,省去麻煩冗餘的C語言的代碼,對比蘋果的Core Data 框架,更加的輕量級和靈活,提供了多線程安全的數據庫操作方法,有效防止數據混亂。
FMDB有三個三個主要的類:
FMDataBase :一個FMDataBase 對象就代表一個單獨的DataBase數據庫,用來執行SQL語句。
FMResultSet: 使用FMResultSet執行查詢後的結果集。
FMDataBaseQueue: 用於多線程執行多個查詢或者更新,他是線程安全的。
@property (nonatomic, strong) FMDatabase *db;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
/*
1.創建數據庫
2.創建表
3.操作
*/
// 1.拼接數據庫地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *sqlFile = [path stringByAppendingPathComponent:@"student.sqlite"];
//該方法接收一個路徑, 它會根據地址創建一個數據庫, 如果不存在就會自動創建
FMDatabase *db = [FMDatabase databaseWithPath:sqlFile];
self.db = db;
if([db open]){
// 2.創建表
NSString *sql = @"CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT , name TEXT, age INTEGER, score REAL);";
// 注意: 在FMDB中除了查詢以外的操作都稱之爲更新
if([db executeUpdate:sql]){
NSLog(@"創建表成功");
}
}
}
- (IBAction)insertClick:(id)sender
{ NSString *sql = @"INSERT INTO t_student(age, score, name) VALUES ('28', 100, 'jonathan');";
if([self.db executeUpdate:sql])
{
NSLog(@"插入成功");
}
}
- (IBAction)selectClick:(id)sender
{
NSString *sql = @"SELECT * FROM t_student;";
// 查詢數據, 會將所有查詢到得數據, 放到results中
FMResultSet *results = [self.db executeQuery:sql];
// 從results中獲取數據
while ([results next]) {
NSString *name = [results stringForColumn:@"name"];
int age = [results intForColumn:@"age"];
double score = [results doubleForColumn:@"score"];
NSLog(@"%@ %d %f", name, age, score);
}
}
FMDataBaseQueue:
@property (nonatomic, strong) FMDatabaseQueue *dbQueue;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1.拼接數據庫地址
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *sqlFile = [path stringByAppendingPathComponent:@"student.sqlite"];
// 創建一個數據庫隊列
FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:sqlFile];
self.dbQueue = dbQueue;
//只要調用dbQueue的inDatabase方法, 系統就會傳遞一個已經打開並且線程安全的數據庫給我們
[dbQueue inDatabase:^(FMDatabase *db) {
// 2.創建表
NSString *sql = @"CREATE TABLE IF NOT EXISTS t_student(id INTEGER PRIMARY KEY AUTOINCREMENT , name TEXT, age INTEGER, score REAL);";
// 注意: 在FMDB中除了查詢以外的操作都稱之爲更新
if([db executeUpdate:sql]){
NSLog(@"創建表成功");
}
}];
}
- (IBAction)insertClick:(id)sender
{
[self.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = @"INSERT INTO t_student(age, score, name) VALUES ('28', 100, 'jonathan');";
if([db executeUpdate:sql])
{
NSLog(@"插入成功");
}
}];
}
- (IBAction)selectClick:(id)sender
{
[self.dbQueue inDatabase:^(FMDatabase *db) {
NSString *sql = @"SELECT * FROM t_student;";
// 查詢數據, 會將所有查詢到得數據, 放到results中
FMResultSet *results = [db executeQuery:sql];
// 從results中獲取數據
while ([results next]) {
NSString *name = [results stringForColumn:@"name"];
int age = [results intForColumn:@"age"];
double score = [results doubleForColumn:@"score"];
NSLog(@"%@ %d %f", name, age, score);
}
}];
}
@end
事務:可以將多條SQL數據綁定在一起,要麼一起執行成功要麼一起執行失敗。
CoreData:
Core Data框架提供了對象-關係映射(ORM)的功能,即能夠將OC對象轉化成數據,保存在SQLite3數據庫文件中,也能夠將保存在數據庫中的數據還原成OC對象。在此數據操作期間,不需要編寫任何SQL語句。