iOS開發-SQLite資料庫在App專案中的設定及使用
在iOS開發中,除了UI頁面以外使用最多的估計是資料物件的儲存了~比如聊天記錄、通訊錄和通訊記錄、瀏覽記錄等等。我們要根據不同的使用方式去對這些資料儲存並使用。常用的有:①沙盒機制 ②屬性列表plist ③SQLite ④CoreData,本文介紹的就是基礎的SQLite的儲存機制,其他的稍後會陸續跟進~
一、首先要注意SQLite的特性:無資料型別的資料庫,所以和在別的平臺上的SQL會有一定的差距
二、常用資料型別
· integer有符號的整數型別
· text字串型別
· real浮點型別
· blob二進位制物件型別
三、在專案中建立資料庫
①在專案中引入sql支援庫:libsqlite3.tbd,還有一個3.0的,我個人用3,不要問我為什麼啊(╯‵□′)╯︵┻━┻
②配置資料庫,建立兩個NSObject類,一個作為model 一個作為資料庫操作
假設我們只儲存兩個資料,一個是又textview寫入的文字,一個是當前時間
針對資料庫的操作就是通過DBOperation來完成,包括表的建立和資料庫連線以及各項操作DataModel.h檔案 #import <Foundation/Foundation.h> @interface DataModel : NSObject // 用來接收文字的屬性 @property (nonatomic , copy)NSString * text; // 文字儲存時間 @property (nonatomic , strong)NSDate * date; // 文字初始化 -(id)initWithText:(NSString *)text Date:(NSDate*)date; @end DataModel.m檔案 #import "DataModel.h" @implementation DataModel -(id)initWithText:(NSString *)text Date:(NSDate*)date{ self = [super init]; if (self) { self.text = text; self.date = date; } return self; } @end
DBOperation.h檔案
#import <Foundation/Foundation.h>
// 引入model
#import "DataModel.h"
// 引入sql的支援庫
#import "sqlite3.h"
// 資料庫檔名
#define DB_Name @"Database.sqlite3"
@interface DBOperation : NSObject
{
// 資料庫物件的成員變數
sqlite3 * database;
}
// 建立一個管理器
+ (DBOperation *)DataBaseManager;
// 資料庫檔案路徑
- (NSString *)Documentsfilepath;
// 開啟資料庫、建立資料庫表
- (void)createDataBaseTable;
// 新增
-(int)addData:(DataModel*)model;
// 刪除
-(int)deleteData:(DataModel*)model;
// 修改
-(int)editData:(DataModel*)model;
// 查詢
-(NSMutableArray*)selectall;
@end
DBOperation.m檔案
#import "DBOperation.h"
@implementation DBOperation
// 建立一個靜態變數
static DBOperation * DataBaseManager = nil;
+ (DBOperation*)DataBaseManager
{
static dispatch_once_t once;
dispatch_once(&once, ^{
DataBaseManager = [[self alloc] init];
[DataBaseManager createDataBaseTable];
});
return DataBaseManager;
}
// 建立一個數據庫,建立名為Text的表設定一個content的屬性
- (void)createDataBaseTable {
NSString *writableDBPath = [self Documentsfilepath];
const char* charpath = [writableDBPath UTF8String];
if (sqlite3_open(charpath, &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO,@"資料庫開啟失敗");
} else {
char *err;
// 建立一個數據庫表,名為 Text 並新增兩個元素 其中textdate為主鍵
NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Text (textdate TEXT PRIMARY KEY, content TEXT);"];
const char* charSql = [sql UTF8String];
if (sqlite3_exec(database, charSql,NULL,NULL,&err) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO, @"建表失敗");
}
sqlite3_close(database);
}
}
// 資料庫存放路徑
- (NSString *)Documentsfilepath {
NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [documentDirectory stringByAppendingPathComponent:DB_Name];
return path;
}
//新增方法
-(int)addData:(DataModel *)model
{
NSString *path = [self Documentsfilepath];
const char* charpath = [path UTF8String];
if (sqlite3_open(charpath, &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO,@"資料庫開啟失敗。");
} else {
NSString *sql = @"INSERT OR REPLACE INTO Text (textdate, content) VALUES (?,?)";
const char* charSql = [sql UTF8String];
sqlite3_stmt *statement;
//預處理過程
if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *strDate = [dateFormatter stringFromDate:model.date];
const char* charDate = [strDate UTF8String];
const char* charContent = [model.text UTF8String];
//繫結引數開始
sqlite3_bind_text(statement, 1, charDate, -1, NULL);
sqlite3_bind_text(statement, 2, charContent, -1, NULL);
//執行插入
if (sqlite3_step(statement) != SQLITE_DONE) {
NSAssert(NO, @"插入資料失敗。");
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return 0;
}
//刪除方法
-(int)deleteData:(DataModel *)model
{
NSString *path = [self Documentsfilepath];
const char* charpath = [path UTF8String];
if (sqlite3_open(charpath, &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO,@"資料庫開啟失敗。");
} else {
NSString *sql = @"DELETE from Text where textdate =?";
const char* charSql = [sql UTF8String];
sqlite3_stmt *statement;
//預處理過程
if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *strDate = [dateFormatter stringFromDate:model.date];
const char * charDate = [strDate UTF8String];
//繫結引數開始
sqlite3_bind_text(statement, 1, charDate, -1, NULL);
//執行
if (sqlite3_step(statement) != SQLITE_DONE) {
NSAssert(NO, @"刪除資料失敗。");
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return 0;
}
//查詢資料方法
-(NSMutableArray*)selectall
{
NSMutableArray *listData = [[NSMutableArray alloc] init];
NSString *path = [self Documentsfilepath];
const char* charpath = [path UTF8String];
if (sqlite3_open(charpath, &database) != SQLITE_OK) {
sqlite3_close(database);
NSAssert(NO,@"資料庫開啟失敗。");
} else {
NSString *sql [email protected]"SELECT textdate,content FROM Text";
const char* charSql = [sql UTF8String];
sqlite3_stmt *statement;
//預處理過程
if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
//執行
while (sqlite3_step(statement) == SQLITE_ROW) {
char *bufDate = (char *) sqlite3_column_text(statement, 0);
NSString *strDate = [[NSString alloc] initWithUTF8String: bufDate];
NSDate *date = [dateFormatter dateFromString:strDate];
char *bufContent = (char *) sqlite3_column_text(statement, 1);
NSString * strContent = [[NSString alloc] initWithUTF8String: bufContent];
DataModel * model = [[DataModel alloc] initWithText:strContent Date:date];
[listData addObject:model];
}
}
sqlite3_finalize(statement);
sqlite3_close(database);
}
return listData;
}
@end
到目前為止資料庫的處理就是基本完成了,剩下的就是去專案裡面開始實際操作,為了方便寫了一個DBManager用來管理引用資料庫操作和model值得傳遞
DBManager.h檔案
#import <Foundation/Foundation.h>
#import "DataModel.h"
#import "DBOperation.h"
@interface DBManager : NSObject
// 新增
-(NSMutableArray *)addTextdata:(DataModel*)model;
// 刪除
-(NSMutableArray *)deleteTextdata:(DataModel*)model;
// 查詢
-(NSMutableArray *)selectall;
@end
DBManager.m檔案
#import "DBManager.h"
@implementation DBManager
// 這個類是用來作為媒介,可用可不用,只是為了讓過程更加清晰
// 新增
-(NSMutableArray *)addTextdata:(DataModel *)model
{
DBOperation * m = [DBOperation DataBaseManager];
[m addData:model];
return [m selectall];
}
// 刪除
-(NSMutableArray *)deleteTextdata:(DataModel *)model
{
DBOperation * m = [DBOperation DataBaseManager];
[m deleteData:model];
return [m selectall];
}
// 查詢
-(NSMutableArray *)selectall
{
DBOperation * m = [DBOperation DataBaseManager];
return [m selectall];
}
@end
③我們回到頁面建立的地方,開始建立檢視,程式碼就不詳細講解了,在附上的demo中有很詳細的註釋,目前就是講一個引導性的思路~在首頁建立一個tableview,用來展示資料,通過nav上的button進入到add頁面,直接呼叫DBManager的add方法,我在這裡添加了一個訊息中心,方便返回頁面時候的傳值。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton * addbtn = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width/2, 100, 120, 30)];
addbtn.backgroundColor = [UIColor redColor];
[addbtn setTitle:@"新增" forState:UIControlStateNormal];
[addbtn addTarget:self action:@selector(add) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addbtn];
textview = [[UITextView alloc]initWithFrame:CGRectMake(0, 150, self.view.frame.size.width, 100)];
textview.backgroundColor = [UIColor blueColor];
[self.view addSubview:textview];
// Do any additional setup after loading the view.
}
-(void)add{
DBManager *manager = [[DBManager alloc] init];
DataModel *model = [[DataModel alloc] init];
model.date = [[NSDate alloc] init];
model.text = textview.text;
NSMutableArray *reslist = [manager addTextdata: model];
[[NSNotificationCenter defaultCenter] postNotificationName:@"backaction" object:reslist userInfo:nil];
[self dismissViewControllerAnimated:NO completion:nil];
}
在首頁先記得宣告訊息中心
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reloadView:)
name:@"backaction"
object:nil];
然後刪除的方法我寫在了tableview的編輯裡面直接完成刪除操作~
// 向左滑動可刪除資料
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
DataModel * model = [self.listData objectAtIndex:[indexPath row]];
DBManager * dm = [[DBManager alloc] init];
self.listData = [dm deleteTextdata: model];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
四、也許有人會問我為什麼增刪改查沒有“改”這一項,我想說我也不知道啊,如果知道的教教我~哈哈,正常來說都是網路請求的資料儲存到本地做查詢和刪除,修改資料都是直接上傳到伺服器上面。表示沒有做過需要在本地修改的資料庫專案~(╯‵□′)╯︵┻━┻(我是菜雞)
附上傳送門:demo
相關推薦
iOS開發-SQLite資料庫在App專案中的設定及使用
在iOS開發中,除了UI頁面以外使用最多的估計是資料物件的儲存了~比如聊天記錄、通訊錄和通訊記錄、瀏覽記錄等等。我們要根據不同的使用方式去對這些資料儲存並使用。常用的有:①沙盒機制 ②屬性列表plist ③SQLite ④CoreData,本文介紹的就是基礎的SQLite
iOS開發之如何在NSURLRequest中設定自定義header請求頭
在使用百度API的時候需要在HTTP請求頭中增加一個apikey,後來我查到已經有相關文章了:http://ju.outofmemory.cn/entry/136630 不過此文章寫得讓人有點看不明白,所以我根據此文章重新介紹如何在NSURLRequest設定自定義請求頭
iOS多語言(國際化)開發(跟隨系統 + APP內手動設定)
一:跟隨系統切換語言 1>建立好專案工程後, 新建一個多語言檔案: 2>新增要設定的語言型別: 3>新增成功 細心的朋友可能會發現在English後面寫的是3 Files Localized,這是因為英語是系
ios開發時,在Xcode中新增多個targets進行版本控制,管理多個相同內容的專案
在ios開發時,我們經常會遇到對同一個app開發多個版本(Pro、Lite、Free)的情況,這裡就涉及到xcode裡通過新增多個targets來進行版本控制的問題了,下面就簡單說明一下: 點選左側的工程名稱,右側會出現PROJECT和TARGETS,點選你現在的target,假如叫A,右鍵彈出選單中,選擇
Android開發-SQLite從資原始檔中資料庫複製到SD到增刪改查-AndroidStudio
覺得博文有用,請點贊,請評論,請關注,謝謝!~最近換工作了,新專案接觸到一些新的知識點,跟大家逐一分享~~首先是SQLite,專案中需要把一個本地幾十兆的本地資料庫放在專案中,實現只用json傳遞少量資料,卻可以實現複雜資料查詢顯示的功能。我分兩塊來說,一個使用SQLiteS
iOS開發之使用App Store加急審核使用說明
when evel bar develop 修復 ios開發 eth sin mar p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 18.0px; font: 14.0px "PingFang SC"; color
iOS開發技巧之:相簿中的GIF圖片的讀取與儲存
大家都知道iOS的系統相簿是不支援gif圖片預覽的。但是,這並不代表系統相簿不能儲存和讀取gif圖片。通過Safari長按gif圖片,選擇儲存到相簿,這時儲存到相簿裡的圖片就是gif的,雖然它不會動。 下面將介紹如何對系統相簿進行gif的讀取與儲存。 什麼是 UTI iOS系統相
iOS 開發之現有老專案引入整合 Flutter
【Flutter 環境配置傳送門】 1、在工程目錄執行如下命令引入 flutter 配置 flutter create -t module flutter_module 補充:新增 flutter 依賴庫流程: cd flutter_modul
在 Create React App 專案中使用 Prettier
前言 如果你只想知道如何在 WebStorm 或 VS Code 中,使用 Prettier 去自動格式化程式碼,那就一拉到底,直奔主題吧。 Prettier 介紹 Prettier 是一個「武斷的」(官網用詞:opinionated)程式碼格式化工具。 它只提供了
Vue專案中設定背景圖片方法
例如css樣式 background:url("../../assets/head.jpg"); 1、在data中定義如下: export default { name: 'productdetailspage', data() { return { n
iOS開發之給navigationbar和view設定同一張圖片
###### 效果一: 今天因為這個小東西被吐槽了...但還是決定記錄一下... 其實說是給navigationbar和view設定同一張圖片是不對的,應該是隱藏navigationbar,再去掉statusbar的背景色,新增view 最開始
在vue cli 3生成的專案中設定less ,sass, stylus的全域性變數
如題: 其實看官方文件我們知道可以使用style-resources-loader這個loader來設定自動化匯入 在每一個關於stylus的檔案中匯入想要的匯入的檔案,你也可以設定為在每一個sass或者less檔案中匯入 但是這是新增了一條規則,來處理自動化匯入。 有沒有其他方式呢?那就是向前處理器
Mac筆記本中是用Idea開發工具在Java專案中呼叫python指令碼遇到的環境變數問題解決
問題描述: mac筆記本本身會自帶幾個python版本,比如python2.7版本,我沒有改動mac預設的python版本,只是安裝了python3.7版本。 使用Pycharm開發Python專案沒有遇到什麼問題。但是在java專案中呼叫py指令碼的話,就有問題了。我的專案需要將Pycharm開發好的p
hibernate結合postgresql資料庫在專案中的使用
新增mvn依賴: <!-- hibernate dependence --> <dependency> <groupId>org.hibernate</groupId> <artifactI
iOS開發 從一個空專案建立ViewController和xib
1、新建一個Empty Application,只選Use Automatic Reference Counting,Use Core Data和Include Unit Tests不選。 2、Command+N 新建檔案,選Cocoa Touch UIViewCont
Vue專案中設定背景圖片
在Vue專案開發中我們經常要向頁面中新增背景圖片,可是當我們在樣式中添加了背景圖片後,編譯打包後,配置到伺服器上時,由於路徑解析的問題,圖片並不能夠正確的顯示出來,如下CSS樣式: background:url("../../assets/head.jpg")
【iOS開發】判斷app啟動的方式(launchOptions)
iOS app啟動的方式有哪些: 自己啟動(使用者手動點選啟動)urlscheme啟動(關於urlScheme的詳解點選開啟連結)本地通知啟動 (自己寫的本地通知啟動,藍芽模組的啟動,地理圍欄的啟動)遠端通知啟動 (後臺伺服器的推送通知)在appdelegate.m
Apicoud+vue開發高效能商城APP專案實戰教程
第一章:專案概述 001:apicloud平臺介紹。 目前所流行的webapp開發平臺的引入,webapp開發的趨勢和能做的事情。 002:知識體系架構介紹。 vue.js的引入介紹,apicloud模組機制的優勢和選型,開發工具phpstorm和webstorm的推薦使用。 第二章:apicloud快速入
Vue專案中設定每個單頁面的標題
兩種實現方法,第一種方法引入外掛,第二種為程式設計方式實現(推薦)首先在路由檔案index.js中給每個單頁面路由新增titleroutes: [{ path: '/', name: '
vue專案中設定全域性變數
跟後端對介面,由於有跨域問題前端設定了代理,但是打包放到伺服器上之後就會出現404問題,原因是這個代理不會在線上環境生效,只是給開發時使用。於是讓後臺更改設定,前端需要直接訪問後臺介面,就需要將後臺地址設為全域性變數,可以在每個元件中直接訪問。查詢記錄方法如下: 1. 單獨新建一個全域性變數模組