連接上一篇文章http://www.cnblogs.com/FBiOSBlog/p/5819418.html。
上一篇文章介紹了OC內部一些方法進行數據的本地存儲,其中包括 NSUser類、Plist文件、解歸檔、手動沙盒存儲。這里將繼續介紹其他的存儲方式。本文主針對Sqlite的存儲做一點介紹。
不管是CoreData還是大部分其他的第三方DB,因為數據的輕量級,都是基於sqlite實現存儲的。目前使用的主流是sqlite3,為了幫助更好的理解(我自己也在初學 階段),我們先從最基本的數據操作接觸,然后再詳細探究CoreData和其他的第三方庫DB庫。
1.理解sqlite
這里對於sqlite有一些常識性的解答,了解即可。OC中,對於Sqlite的支持使用的是一套C語言的API,對於OC開發者來說,使用來並不是難事。
2.基本的sqlite操作/使用。
對於我們普通的使用人員來說,我們關心的是如何使用數據達到存儲數據的要求。接下來,我就使用一個小小的案例展示:
1).搭建sqlite使用環境。
2).創建數據/關閉數據庫
3).對數據庫中的數據進行增刪改查
1).Xcode項目中,搭建sqlite使用環境。
添加sqlite依賴庫,target >build phases> link binary with libraries ,搜索sqlite ,發現有兩個庫類:libsqlite3.tdb,libsqlite3.0.tdb,理論上來說添加哪一個都是一樣的,不同的是libsqlite3.0.tdb 指向的是庫的當前版本最新的libsqlite3.tdb,也即是當Xcode庫更新,程序依賴的庫也隨之更新。如非必要,建議添加 libsqlite3.0.tdb。
比如我們需要寫一個操作sqlite 的工具 SqliteTool,為了保證當前數據庫在工程里是唯一的,我們用單例的方式創建SqliteTool。在這之前應該為SqliteTool添加頭文件 #import <sqlite3.h>。
SqliteTool.h 文件
#import <Foundation/Foundation.h> #import <sqlite3.h> @interface SqliteTool : NSObject
+ (SqliteTool *)shareinstance;
@end
.m文件
#import "SqliteTool.h"
#import "TestModel.h"
@implementation SqliteTool
{
sqlite3 *_dbPoint; //用於保存數據庫對象的地址
}
+ (SqliteTool *)shareinstance{
static SqliteTool *tool = nil;
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
tool=[[SqliteTool alloc] init];
});
return tool;
}
這樣,在SqliteTool中我們配置好了使用環境。下一步是使用。
2).創建數據/關閉數據庫
打開數據庫。iOS 中,數據庫存儲在沙盒中,上一篇講到,如果數據並不是很大並希望跟隨應用備份,那么數據應該存Documents文件中。
我們給SqliteTool添加一個方法
- (BOOL)creatSqliteDB
創建數據庫:
//如果系統根據這個文件路徑查找的時候有對應文件則直接打開數據庫,如果沒有則會創建一個相應的數據庫 - (BOOL)creatSqliteDB{ NSString *sqitePath = [NSHomeDirectory() stringByAppendingPathComponent:@"testModel.sqlite"];
int result = sqlite3_open([sqitePath UTF8String], &_dbPoint); //在指定路徑下,創建一個數據,並將數據庫的地址賦值給_dbPoint
if (result == SQLITE_OK) {
NSLog(@"數據庫打開成功"); NSLog(@"%@",sqitePath); return YES; }else{ NSLog(@"數據庫打開失敗"); } return NO; }
給SqliteTool添加一個方法
- (BOOL)closeSqliteDB
關閉數據庫
- (BOOL)closeSqliteDB{ int result = sqlite3_close(_dbPoint); if (result==SQLITE_OK) { NSLog(@"數據庫關閉成功"); return YES; }else{ NSLog(@"數據庫關閉失敗"); } return NO; }
3).使用數據庫進行數據的增刪改查
創建好了Sqlite,接下來我們要使用SqliteTool工具對TestModel類進行存儲了。 當然基本數據類型一樣可以存儲。 假設TestModel類的屬性是這樣的:
.h
#import <Foundation/Foundation.h> @interface TestModel : NSObject <NSCoding> @property (nonatomic,strong) NSString *name; @property (nonatomic,assign) NSInteger age; @property (nonatomic,strong) NSString *sex; @end
我希望SqlilteTool能夠存貯這個testModel,往下看。
我們在存儲數據的時候,先要在數據庫中建立一張表,將數據存入表中。之后對表中的數據進行增刪改查。意思就是將數據都寫入一張表格里面,我們通過對表格操作來進行數據的增刪改查。
SqliteTool.h 中聲明以下方法
//創建一個存儲列表。 一個數據庫可以創建很多列表,用來存儲不同的對象。 - (BOOL)createTable; //往表中插入數據 - (void)insertModel:(TestModel *)model; //更新表中的數據 - (void)updateModel:(TestModel *)model; //刪除表中的數據 - (void)deletedateModel:(TestModel *)model; //查看表中的數據 - (NSMutableArray *)selectAllModel;
.m實現
創建table
/* 創建一個存儲列表。 一個數據庫可以創建很多列表,用來存儲不同的對象。 primary key 是主鍵的意思,主健在當前表里數據是唯一的,不能重復,可以唯一標識一條數據,一般是整數 autoincrement自增,為了讓主鍵不重復,會讓主鍵采用自增的方式 if not exists 如果沒有表才會創建,防止重復創建覆蓋之前數據 */ - (BOOL)createTable{ //語句中包涵的信息應該仔細, nsstring類型對應的是text 數組對應arr 整型對應integer 等等 NSString *sqlStr = @"create table if not exists test(number integer primary key autoincrement,name text,age integer,sex text)"; //執行這條sql語句 int result = sqlite3_exec(_dbPoint, [sqlStr UTF8String], nil, nil, nil); if (result == SQLITE_OK) { NSLog(@"表創建成功"); return YES; }else{ NSLog(@"表創建失敗"); } return NO; }
增
//往表中插入數據 - (BOOL)insertModel:(TestModel *)model{ NSString *sqlStr=[NSString stringWithFormat:@"insert into test (name,age,sex) values ('%@','%ld','%@')",model.name,model.age,model.sex]; //執行sql語句 int result = sqlite3_exec(_dbPoint, [sqlStr UTF8String], nil, nil, nil); if (result == SQLITE_OK) { NSLog(@"添加%@成功",model.name); return YES; }else { NSLog(@"添加model失敗"); } return NO; }
刪
//刪除表中的內容 - (BOOL)deletedateModel:(TestModel *)model{ NSString *sqlStr=[NSString stringWithFormat:@"delete from test where name='%@'",model.name]; // NSString *sqlStr=[NSString stringWithFormat:@"delete from test"]; //不添加添加條件則刪除所有數據 //執行sql語句 int result = sqlite3_exec(_dbPoint, [sqlStr UTF8String], nil, nil, nil); if (result == SQLITE_OK) { NSLog(@"刪除%@成功",model.name); return YES; }else { NSLog(@"刪除失敗"); } return NO; }
改
//更新表中的數據 - (BOOL)updateModel:(TestModel *)model{ NSString *sqlStr= [NSString stringWithFormat:@"update test set sex='%@',age=%ld where name='%@'",model.sex,model.age,model.name]; //執行sql語句 int result = sqlite3_exec(_dbPoint, [sqlStr UTF8String], nil, nil, nil); if (result == SQLITE_OK) { NSLog(@"修改成功"); return YES; }else { NSLog(@"修改失敗"); } return NO; }
查
/* 查詢邏輯 1.先從本地的數據庫中讀取某張表里的所有數據 2.然后逐條進行讀取,對model進行賦值 3.把已經賦值好得model放到數組中,並且返回 4.在語句里*是通配符的意思,通過一個*相當於代替了表里的所有的字段名 5.接下來需要定義一個跟隨指針,它用來遍歷數據庫表中的每行數據 6.第三個參數:查詢語句字數限制,-1是沒有限制 */ //查看表中的數據 - (NSMutableArray *)selectAllModel{ NSString *sqlStr=@"select * from test"; sqlite3_stmt *stmt=nil; int result=sqlite3_prepare_v2(_dbPoint, [sqlStr UTF8String], -1, &stmt, nil);//這個方法相當於把數據庫和跟隨指針關聯,一同完成查詢功能 NSMutableArray *modelArr = [NSMutableArray array]; //初始化學生類數組 獲取遍歷得到的數據 if (result == SQLITE_OK) { NSLog(@"查詢成功"); //開始遍歷查詢數據庫的每一行數據 while (sqlite3_step(stmt) == SQLITE_ROW) { //讓跟隨指針進行遍歷查詢,如果沒有行,才會停止循環 //滿足條件,則逐列的讀取內容 //第二個參數表示當前這列數據在表的第幾列 const unsigned char *name = sqlite3_column_text(stmt, 1); int age = sqlite3_column_int(stmt, 2); const unsigned char *sex = sqlite3_column_text(stmt,3); //把列里的數據再進行類型的轉換 NSInteger modelAge = age; NSString *modelName = [NSString stringWithUTF8String:(const char *)name]; NSString *modelSex = [NSString stringWithUTF8String:(const char *)sex]; //給對象賦值,然后把對象放到數組里 TestModel *model = [[TestModel alloc] init]; model.name = modelName; model.sex = modelSex; model.age = modelAge; [modelArr addObject:model]; } }else{ NSLog(@"查詢失敗"); } return modelArr; }
方法寫完,現在調用測試。
//創建對象 並賦值 TestModel *model = [[TestModel alloc]init]; model.name = @"小明"; model.age = 25; model.sex = @"man"; TestModel *model1 = [[TestModel alloc]init]; model1.name = @"小花"; model1.age = 23; model1.sex = @"woman"; if([[SqliteTool shareinstance] creatSqliteDB]){ if([[SqliteTool shareinstance] createTable]){ //增 if([[SqliteTool shareinstance] insertModel:model] && [[SqliteTool shareinstance] insertModel:model1]){ NSLog(@"增加model、model1"); NSLog(@"%@",[[SqliteTool shareinstance] selectAllModel]); } //刪 if([[SqliteTool shareinstance] deletedateModel:model1]){ NSLog(@"刪除model1"); NSLog(@"%@",[[SqliteTool shareinstance] selectAllModel]); } //改 model.age = 28; //注意 這里因為是以名字作為索引對象,因此名字是不能修改的, 如果要修改名字,應該另外增加一個不變屬性作為索引 if([[SqliteTool shareinstance] updateModel:model]){ NSLog(@"修改model"); NSLog(@"%@",[[SqliteTool shareinstance] selectAllModel]); } //查 NSLog(@"%@",[[SqliteTool shareinstance] selectAllModel]); } }
打印結果