[iOS] 在iOS裡操作SQLite筆記 (上)
這邊來討論iOS在存取本地端資料庫的方式,在討論iOS的Core Data前,先來看一下比較簡單的土法煉鋼又不太健康也方式XD,來在iOS裡面操作SQLite資料庫。:
這一個部分的範例會關係到UITableView的知識,UITableView的部分可以看這個章節
http://www.dotblogs.com.tw/toysboy21/archive/2013/11/19/130485.aspx
1. 在Xcode建立一個新的專案,專案名稱為Sqlite。
2. 在iOS App裡面要使用SQLite的資料庫,首先要在你的專案中加入libsqlite3.dylib Framework的參考。
3. 要使用Sqlite資料庫的操作,必須在會使用資料庫的Header檔案引用Sqlite3.h的標頭檔。
所以在專案中的ViewController.h檔案裡面需要 #import <sqlite3.h>
*Note:
如果要引用的專案標頭檔在這個專案裡很多檔案都會被引用,那可以在
專案-prefix.pch檔案裡面統一include這個檔案。
4. 點選[Main.storyboard]在畫面中新增一個文字方塊,buton按鈕與UITableView。
5. 點選在ViewController.h 實作<UITableViewDelegate,UITableViewDataSource>兩個介面以及下方的程式碼。
@interface ViewController : UIViewController
{
//類別變數
sqlite3* db;
//動態陣列:
NSMutableArray *TabelDatas;
}
//新增資料的textbox
@property (weak, nonatomic) IBOutlet UITextField *mytxt;
//按鈕事件
- (IBAction)mybtn_click:(id)sender;
//UItable與Controller連結的IBoutlet
@property (weak, nonatomic) IBOutlet UITableView *mytable;
//執行SQL指令,並且回傳statement(RS)物件
- (sqlite3_stmt *) executeQuery:(NSString *) query;
//執行SQL指令,並且回傳NSMutableArray物件
- (NSMutableArray *) statementtoMSarray:(sqlite3_stmt *) sqlstmt;
@end
6. 點選在ViewController.m檔案,實作與UITableView相關的方法。
//按鈕Button.TouchUpInside事件
- (IBAction)mybtn_click:(id)sender {
// 組合寫資料庫的語法(這總使用使用者輸入的資料來組SQLcommand是比較不建議的做法,會有sql injection的風險)
NSString *sql = [NSString stringWithFormat:@"INSERT INTO test (test001) VALUES ('%@')",self.mytxt.text];
char *errMsg;
if(sqlite3_exec(db, [sql cStringUsingEncoding:NSUTF8StringEncoding], NULL, NULL, &errMsg) == SQLITE_OK){
NSLog(@"寫入資料庫成功, %s", errMsg);
}else{
NSLog(@"寫入資料庫失敗, %s", errMsg);
}
//從資料庫裡面取出所有的資料
NSString *sql2 = [NSString stringWithFormat:@"select * from test"];
//呼叫executeQuery方法,取得statement
sqlite3_stmt *statement = [self executeQuery:sql2];
//呼叫statementtoMSarray方法,傳入statement物件取回陣列值
TabelDatas = [self statementtoMSarray:statement];
//把陣列值傳給UITableView物件
[self.mytable reloadData];
}
//執行查詢指令 並且回傳一個 statement集合
- (sqlite3_stmt *) executeQuery:(NSString *) query{
sqlite3_stmt *statement;
sqlite3_prepare_v2(db, [query UTF8String], -1, &statement, nil);
return statement;
}
//將statement物件轉換成一個NSArray物件
- (NSArray *) statementtoMSarray:(sqlite3_stmt *) sqlstmt{
TabelDatas = [[NSMutableArray alloc]init];
NSString *data;
while (sqlite3_step(sqlstmt) == SQLITE_ROW) {
data = [NSString stringWithUTF8String:(char *)sqlite3_column_text(sqlstmt,0)];
[TabelDatas addObject:data];
}
return TabelDatas;
}
7. 在ViewController.m檔案裡面實作<UITableViewDelegate,UITableViewDataSource>兩個介面的方法。
//這個方法是用來指定有多少的Section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
// Return the number of sections.
return 1;
}
//這個方法是用來指定每個Section裡面有多少Rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// return 1;
return [TabelDatas count];
}
//用來產生Cell的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Configure the cell.
cell.textLabel.text = [TabelDatas objectAtIndex:[indexPath row]];
return cell;
}
8.如果在你的App裡面如果沒有資料庫,iOS會在App的Document資料夾裡面自動建立資料庫檔案。
當你把你的APP部署到模擬器的時候,可以在以下的位置找到你的資料庫。
~/library/Application Support/iPhone Simulator/版本/Applications/你的App/Documents/
9. 如果一個App裡面你已經預先放了一個資料庫,你可以在AppDelegate.m檔案裡面的
- (BOOL)application:didFinishLaunchingWithOptions: 事件裡面撰寫底下的程式把
你預先準備好的資料庫Copy到Documents資料夾下。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//將資料庫檔案複製到具有寫入權限的目錄
NSFileManager *fm = [[NSFileManager alloc]init];
NSString *src = [[NSBundle mainBundle]pathForResource:@"sample" ofType:@"sqlite"];
NSString *dst = [NSString stringWithFormat:@"%@/Documents/sample.sqlite",NSHomeDirectory()];
//APP啓用的時候在@/Documents 沒有資料庫,所以要從APP裡面把sample.sqlite資料庫拷貝到 @/Documents/ 資料夾下
//拷貝完資料庫後,刪除掉App裡面的資料庫檢查目的地的檔案是否存在,如果不存在則複製資料庫
// if(![fm fileExistsAtPath:dst]){
// [fm copyItemAtPath:src toPath:dst error:nil];
// [fm removeItemAtPath:src error:nil];
// }
//每次都把資料庫Copy到Document資料夾下
[fm removeItemAtPath:dst error:nil];
[fm copyItemAtPath:src toPath:dst error:nil];
return YES;
}
10.執行測試App,測試寫資料到資料庫中。
11.要如何開啓這個SQLite資料庫的檔案。
免費可以操作SQLite的產品很多,這邊我使用的是一個在FireFox瀏覽器下的一個工具套件。
SQLite Manager。
因為預設資源庫的資料夾是被隱藏起來的,所以這邊在終端機視窗裡面下底下的指令,
顯示資源庫資料夾。
chflags nohidden ~/Library
接著就可以去開啓部署到模擬器的App裡面的SQLite資料庫。
你可以在下方路徑找到相對應的App與資料庫。
~/library/Application Support/iPhone Simulator/版本/Applications/你的App/Documents/
開啓資料庫後,可以看到剛剛我們在資料庫裡面新增的資料。
範例程式下載:https://github.com/twbenlu/iOSSQLite/tree/master