一、前言
sqlite3數據庫是一種輕量型的數據庫,系統中已經默認安裝了,可以通過終端來查看:
首先進入模擬器的沙盒目錄中,我們在Documents目錄下創建一個sql文件,然後使用sqlite3來訪問這個文件。在終端中,可 以使用sql語句來對錶進行操作,這裏就不在贅述了,下面主要介紹使用代碼來對錶進行操作。
二、使用代碼對數據庫進行增、刪、改、查。
2.1 導入頭文件
首先在工程下的BuildPHases下找到LinkBinary....什麼的,然後點擊下面的加號,添加sql的庫,我們選擇添加的是第二個搜索結果。
然後再用到數據庫的類中導入即可
#import <sqlite3.h>
由於OC裏面有關數據庫的操作都是基於C語言的,所以有可能不會提示。
2.2 正式使用
1. 打開數據庫
-(void)open{
//filename:數據庫的具體路徑
//ppdb:數據庫實例的地址
NSString * filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"db.sql"];
int status = sqlite3_open(filePath.UTF8String, &_db);
if(status == SQLITE_OK){
//打開成功
NSLog(@"打開成功");
}else{
NSLog(@"打開失敗");
}
}
首先我們在Documents目錄下需要創建一個名爲 db.sql 的文件,所以我們拼接出這個文件的路徑。然後使用 sqlite_open的方法,這個方法接受兩個參數,一個是數據庫的具體的路徑,第二個是數據庫實例的地址。在之前已提過OC中的數據庫的操作都是基於C語言的,所以兩個參數的都是C語言中的類型,需要轉化。這個方法調用之後,會將數據庫實例的地址放入我們定義的屬性變量 db 中(注意這個屬性變量也是C語言類型的指針,所以用assign來修飾),這個方法返回一個狀態值,表示數據打開成功與否。
2. 創建表
-(void)createTable{
//1.創建sql語句
NSString * sql = @"create table student (id integer primary key autoincrement,name text,age integer)";
//2.執行語句
int status = sqlite3_exec(self.db, sql.UTF8String,NULL, NULL, NULL);
if (status == SQLITE_OK) {
NSLog(@"創建表成功");
}else{
NSLog(@"創建表失敗");
}
}
使用sqlite3_exec()方法來執行一個sql語句,它接受五個參數,第一個參數就是這個數據庫的實例,第二個就是執行的sql語句,第三個參數是一個函數指針,就是sql語句執行成功之後執行的回調函數,相當於OC中的block,第四個參數是一個任意類型的指針表示第一個需要回調的參數,最後一個參數表示的錯誤信息。這個方法返回一個狀態值,表示創建表是否成功。
3. 向表中插入,刪除,更改數據
-(void)insert{
NSString * sql = @"insert into student(name,age) values('Jack',20)";
if(sqlite3_exec(self.db,sql.UTF8String, NULL, NULL, NULL)==SQLITE_OK){
NSLog(@"插入數據成功");
}else{
NSLog(@"插入數據失敗");
}
}
我們向數據庫中插入一條數據,也是通過哦 sqlite3_exec()函數來完成,完成後可以通過訪問沙盒路徑下的sql文件來查看數據是否已經被插入表中。同理刪除,更改數據只是sql語句的不同,這裏不再贅述。
4. 查詢數據
-(void)select{
//1.定義查詢語句
NSString * sql = @"select * from student";
//2.準備查詢語句(預處理) 將數據緩存到另外一個地方去->stmt
sqlite3_stmt * stmt = NULL;
if (sqlite3_prepare(self.db, sql.UTF8String, -1, &stmt, NULL)==SQLITE_OK) {
NSLog(@"預處理成功");
//3.一條條讀數據
while (sqlite3_step(stmt)==SQLITE_ROW) {
char * name = (char *) sqlite3_column_text(stmt, 1);
int age = (int) sqlite3_column_int(stmt, 2);
NSData * data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 3) length:sqlite3_column_bytes(stmt, 3)];
UIImage * imag = [UIImage imageWithData:data];
NSLog(@"%s,%d,%@",name,age,imag);
}
}else{
NSLog(@"預處理失敗");
}
//釋放開闢的內存空間
sqlite3_finalize(stmt);
}
查詢語句相對上面的三種操作來說稍微複雜一些,我們一步步來說,首先是定義查詢語句,然後是對sql語句進行預處理,在預處理的過程中,我們定義了一個 sqlite3_stmt類型的變量 stmt,這裏有點像 servlet中的PreparedStatement,定義這個變量的原因是將查詢所得的數據放到這個變量中。然後調用 sqlite3_prepare()這個方法,這個方法接受五個參數,前兩個參數不再贅述,第三個參數指的是sql語句的長度,我們傳-1表示計算機自己計算sql語句的長度,第四個參數就是 stmt的地址,這個函數將查詢到的結果集放入這個地址指向的空間中,最後一個參數指向未執行的SQL語句。然後循環讀取stmt中的數據,通過 sqlite3_step(stmt) 來判斷stmt是否遍歷結束了,然後通過 sqlite3_column_xxxx() 來獲取相應的數據,如果獲取的數據包含圖片,視頻等數據,需要將查詢的結果轉換爲二進制, 通過sqlite3_column_bytes() 來計算這個字段(圖片,視頻)字段的字節數。最後使用 sqlite3_finalize()方法來釋放掉這個指針指向的空間。
5. 插入圖片,視頻,音頻數據
-(void)multipleInsert{
UIImage * image = [UIImage imageNamed:@"1"];
NSData * imgeData = UIImagePNGRepresentation(image);
NSLog(@"%@",imgeData);
//佔位符 ?
NSString * sql = @"insert into student(name,age,icon) values(?,?,?)";
//預處理
sqlite3_stmt * stmt = NULL;
if(sqlite3_prepare(self.db, sql.UTF8String,-1,&stmt, NULL)==SQLITE_OK){
NSLog(@"預處理成功");
//綁定數據
sqlite3_bind_text(stmt, 1,"Harry",-1, NULL);
sqlite3_bind_int(stmt, 2, -1);
sqlite3_bind_blob(stmt, 3,imgeData.bytes,(int)imgeData.length, NULL);
//將綁定的數據保存到數據庫中
if(sqlite3_step(stmt)==SQLITE_DONE){
NSLog(@"保存成功");
}else{
NSLog(@"保存失敗");
}
}else{
NSLog(@"預處理失敗");
}
//釋放開闢的內存空間
sqlite3_finalize(stmt);
}
這裏以插入圖片數據爲例,首先我們將圖片轉化爲二進制數據,然後定義sql語句,這裏使用使用佔位符來表示對應字段的值,因爲圖片的二進制數據很多,不能直接拼接進去。接着進行預處理,預處理成功之後,通過 sqlite3_bind_xxxx()方法來將不同類型的數據綁定到對應占位符上,然後 調用 sqlite3_step(stmt) 方法來進行具體操作,這個方法返回一個狀態值,表示所進行的操作是否成功。同樣 需要釋放stmt的空間。