SQLite數據庫

我們在寫項目中常常要求數據持久化 在iOS編程中數據持久化的方式有歸檔/反歸檔將數據寫入本地或者利用數據庫將數據接入到本地都可以實現數據持久化 下面就來介紹一下iOS中使用的一種數據庫SQLite
SQLite是一種輕型嵌入式數據庫 在iOS和安卓開發(fā)中都會使用到 它占用內存小 大概幾百k 而且數據處理速度要比Mysql棱貌、PostgreSQL這兩款數據庫快
在寫數據庫時 一定不要把SQL語句寫錯了 下面我們通過代碼來看一下 怎樣去實現一個數據庫

#import <Foundation/Foundation.h>
#import <sqlite3.h>  // 3.0 是3的替身文件
@class Student;

NS_ASSUME_NONNULL_BEGIN
@interface SQLiteDataBaseManager : NSObject {
sqlite3 *dbPoint;
}
// 寫一個數據庫管理類
// 單例 方法一個工程中只包含這一個對象
+ (SQLiteDataBaseManager *)sharedManager;
// 打開數據庫
- (BOOL)openSQLite3;
// 關閉數據庫
- (BOOL)closeSQLite3;
// 創(chuàng)建表
- (BOOL)createTable;
// 插入 / 添加數據
- (BOOL)insertStu:(Student *)stu;
// 刪除數據
- (BOOL)deleteStu:(Student *)stu; // 刪除一個
- (BOOL)deleteAll; // 刪除全部
// 修改 / gengxin
- (BOOL)updateOldName:(NSString *)oldName newName:    (NSString *)newName;
// 查詢數據
- (__kindof NSArray *)selectAll;
@end
NS_ASSUME_NONNULL_END


#import "SQLiteDataBaseManager.h"
#import "Student.h"

@implementation SQLiteDataBaseManager
// 單例 創(chuàng)建方式 只有一個對象(在整個程序運行過程中 一直存在 不要給他釋放)
// 內存管理中 單例不能被釋放
+ (SQLiteDataBaseManager *)sharedManager {
// 靜態(tài)變量 static + 類名
static SQLiteDataBaseManager *manager = nil;
// 保證線程安全執(zhí)行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // 創(chuàng)建
    manager = [[SQLiteDataBaseManager alloc] init];
});
return manager;
}

// 打開數據庫
- (BOOL)openSQLite3 {
// 獲取沙盒
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [array firstObject];
// 數據庫SQLite3文件類型.db
NSString *dbPath = [path stringByAppendingPathComponent:@"student.db"];
NSLog(@"%@", dbPath);
// UTF8String: 將OC字符串轉換成C語言中的字符串
// 參數1: 數據庫文件路徑
// 參數2: 指向指針的指針 該指針可以被修改 數據庫管理的指針
int result = sqlite3_open([dbPath UTF8String], &dbPoint);
BOOL isOpen = YES;
// sqlite3_open 當路徑文件不存在時 路徑文件會被sqlite3_open創(chuàng)建 并打開
// 當sqlite3_open 存在時 文件直接被打開
// sqlite3_open 返回值為int型 "0"代表成功(SQLite_OK)    "1"代表失敗
if (result == SQLITE_OK) {
    NSLog(@"打開數據庫成功");
    isOpen = YES;
} else {
    NSLog(@"打開數據庫失敗");
    isOpen = NO;
}
return isOpen;
}

// 關閉數據庫
- (BOOL)closeSQLite3 {
// 關閉數據庫時 如果數據庫是打開狀態(tài) 會關閉成功
// 關閉數據庫時 如果數據庫時關閉狀態(tài) 會顯示失敗 原因21 庫不存在
int result = sqlite3_close(dbPoint);
return [self isOperationResult:result alertText:@"關閉數據庫"];
}
// 創(chuàng)建表
- (BOOL)createTable {
// SQL語句 create table 表名 (字段1 類型 約束, 字段2 類型 約束........)
//    NSString *createSQL = @"create table stu(stu_id integer primary key, stu_name text)";
// primary key: 一個表有且只有一個主鍵
// autoincrement: 自增 添加完該字段 系統(tǒng)會自己創(chuàng)建一個數據庫表 sqlite_sequence 用來保存自增的值
// not null: 不能為空 如果為空 SQL會報錯
// 刪除一個表 drop table + 表名(SQL語句)
NSString *createSQL = @"create table stu2(stu_id integer primary key autoincrement, stu_name text NOT NULL)";
// 執(zhí)行SQL語句 參數1: 數據庫指針 參數2:SQL語句 剩下的都是null
int result = sqlite3_exec(dbPoint, [createSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"創(chuàng)建表"];
}

- (BOOL)insertStu:(Student *)stu {
NSString *insertSQL = [NSString stringWithFormat:@"insert into stu2 values (null, '%@')", stu.stu_name];
// 如果設置了自增 將值填寫為null 默認從1開始 如果填寫其他值 例如:填入7 值將會從7開始計算 并存儲在sqlite_sequence
//    NSString *insertSQL = @"insert into stu7 values (null, 'Eason')";
int result = sqlite3_exec(dbPoint, [insertSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"插入數據"];
}
- (BOOL)deleteStu:(Student *)stu {
NSString *deleteSQL = [NSString stringWithFormat:@"delete from stu2 where stu_id = %ld", stu.stu_id];
int result = sqlite3_exec(dbPoint, [deleteSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"刪除一條數據"];
}

- (BOOL)deleteAll {
NSString *deleteSQL = @"delete from stu2 where 1=1";
int result = sqlite3_exec(dbPoint, [deleteSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"刪除全部"];
}

- (BOOL)updateOldName:(NSString *)oldName newName:(NSString *)newName {
// update 表名 字段名 = 新值 where 字段名 = 舊值
NSString *updateSQL = [NSString stringWithFormat:@"update stu2 set stu_name = '%@' where stu_name = '%@'", newName, oldName];
int result = sqlite3_exec(dbPoint, [updateSQL UTF8String], NULL, NULL, NULL);
return [self isOperationResult:result alertText:@"更新"];
}

- (__kindof NSArray *)selectAll {
sqlite3_stmt *stmt = NULL;
NSString *selectAll = @"select * from stu2";
// 參數1: 數據庫指針
// 參數2: SQL語句
// 參數3: SQL語句長度 -1
// 參數4: 替身 將查詢到的內容放到替身中 并將替身返回
int result = sqlite3_prepare(dbPoint, [selectAll UTF8String], -1, &stmt, NULL);
NSMutableArray *stuArray = [NSMutableArray array];
if (result == SQLITE_OK) {
    // 循環(huán) 遍歷替身內容 直到 SQLITE_DONE
    // step 查詢替身中有沒有其他數據 當包含有其他數據時 結果為SQLITE_ROW 當不包含其他數據時 結果為 SQLITE_DONE 結束執(zhí)行
    while (sqlite3_step(stmt) == SQLITE_ROW) {
    // 取對應的每一列數據
        int stu_id = sqlite3_column_int(stmt, 0); // 取第0列
        const unsigned char *stu_name = sqlite3_column_text(stmt, 1); //
        Student *stu = [[Student alloc] init];
        stu.stu_id = stu_id;
        stu.stu_name = [NSString stringWithUTF8String:(const char *)stu_name];
        [stuArray addObject:stu];
    }
}
// 替身用完了要銷毀
sqlite3_finalize(stmt);
return stuArray;
}
- (BOOL)isOperationResult:(int)result alertText:(NSString *)alertText {
BOOL isOperation = YES;
if (result == SQLITE_OK) {
    NSLog(@"%@成功", alertText);
    isOperation = YES;
} else {
    NSLog(@"%@失敗", alertText);
    isOperation = NO;
}
return isOperation;
}
@end

#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, assign) NSInteger stu_id;
@property (nonatomic, copy) NSString *stu_name;
@end

#import "ViewController.h"
#import "SQLiteDataBaseManager.h"
#import "Student.h"
@interface ViewController ()
@property (nonatomic, strong) SQLiteDataBaseManager *dataBaseManager;
@end

@implementation ViewController
- (IBAction)openSQLiteButton:(id)sender {
[_dataBaseManager openSQLite3];
// 注意: 使用SQLite需要引入sqlite3.0.tdb
// sqlite3.tdb 和sqlite3.0.tdb區(qū)別
// sqlite3.0.tdb 是sqlite3.tdb的提審文件 放置誤刪
}

- (IBAction)closeSQLite:(id)sender {
[_dataBaseManager closeSQLite3];
}
- (IBAction)createTable:(id)sender {
[_dataBaseManager createTable];
}
- (IBAction)insertStu:(id)sender {
Student *stu = [[Student alloc] init];
stu.stu_id = 17;
stu.stu_name = @"Andy";
[_dataBaseManager insertStu:stu];
}

- (IBAction)deleteStu:(id)sender {
Student *stu = [[Student alloc] init];
stu.stu_id = 17;
stu.stu_name = @"Andy";
//    [_dataBaseManager deleteStu:stu];
[_dataBaseManager deleteAll];
}

- (IBAction)update:(id)sender {
[_dataBaseManager updateOldName:@"Andy" newName:@"Mary"];
}

- (IBAction)selectAll:(id)sender {
NSArray *array = [_dataBaseManager selectAll];
NSLog(@"%@", array);
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末闯捎,一起剝皮案震驚了整個濱河市抽减,隨后出現的幾起案子凤壁,更是在濱河造成了極大的恐慌,老刑警劉巖荷科,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笔链,死亡現場離奇詭異,居然都是意外死亡趣惠,警方通過查閱死者的電腦和手機狸棍,發(fā)現死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來味悄,“玉大人草戈,你說我怎么就攤上這事∈躺” “怎么了唐片?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涨颜。 經常有香客問我费韭,道長,這世上最難降的妖魔是什么庭瑰? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任星持,我火速辦了婚禮,結果婚禮上见擦,老公的妹妹穿的比我還像新娘钉汗。我一直安慰自己,他們只是感情好鲤屡,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布损痰。 她就那樣靜靜地躺著,像睡著了一般酒来。 火紅的嫁衣襯著肌膚如雪卢未。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音辽社,去河邊找鬼伟墙。 笑死,一個胖子當著我的面吹牛滴铅,可吹牛的內容都是我干的戳葵。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼汉匙,長吁一口氣:“原來是場噩夢啊……” “哼拱烁!你這毒婦竟也來了?” 一聲冷哼從身側響起噩翠,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤戏自,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后伤锚,有當地人在樹林里發(fā)現了一具尸體擅笔,經...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年屯援,在試婚紗的時候發(fā)現自己被綠了猛们。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡狞洋,死狀恐怖阅懦,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情徘铝,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布惯吕,位于F島的核電站惕它,受9級特大地震影響,放射性物質發(fā)生泄漏废登。R本人自食惡果不足惜淹魄,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堡距。 院中可真熱鬧甲锡,春花似錦、人聲如沸羽戒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽易稠。三九已至缸废,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背企量。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工测萎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人届巩。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓硅瞧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恕汇。 傳聞我的和親對象是個殘疾皇子腕唧,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內容