IOS學習筆記28—SQLite3第三方庫之FMDB
SQLite是一種小型的輕量級的關系型數據庫,在移動設備上使用是非常好的選擇,無論是Android還是IOS,都內置了SQLite數據庫,現在的版本都是SQLite3。在IOS中使用SQLite如果使用SDK提供的方法,特別麻煩也不利于理解和使用,在之前的http://blog.csdn.net/tangren03/article/details/7781930文章中就是使用IOS的SDK自帶的SQLite API來使用數據庫,感覺使用很不方便,今天就講講一個針對IOS的SQlite API封裝的第三方庫FMDB,FMDB對SDK中的API做了一層封裝,使之使用OC來訪問,使用方便而且更熟悉。FMDB的下載地址https://github.com/ccgus/fmdb。
FMDB主要涉及兩個類,FMDatabase和FMResultSet,前者類似于Android中的SQLiteOpenHelper或SQLiteDatabase,FMResultSet類似于Android中的Cursor,用來存儲結果集。
下載完FMDB源碼后把文件拖到工程中,并導入SQLite支持庫,工程目錄如下:
然后就是這個Demo的完整截圖:
然后就來看看如何操作FMDB:
//點擊按鈕后執行保存到數據庫的操作
- (IBAction)saveButtonClicked:(id)sender {
//獲取Document文件夾下的數據庫文件,沒有則創建
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"];
//獲取數據庫并打開
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
if (![database open]) {
NSLog(@"Open database failed");
return;
}
//創建表(FMDB中只有update和query操作,出了查詢其他都是update操作)
[database executeUpdate:@"create table user (name text,gender text,age integer)"];
//插入數據
BOOL insert = [database executeUpdate:@"insert into user values (?,?,?)",nameTextField.text,genderTextField.text,ageTextField.text];
if (insert) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"保存成功" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
[database close];
}
操作成功后彈出提示框:
//點擊按鈕后執行查詢操作
- (IBAction)queryButtonTapped:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *dbPath = [documentPath stringByAppendingPathComponent:@"user.db"];
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
if (![database open]) {
return;
}
//不需要像Android中那樣關閉Cursor關閉FMResultSet,因為相關的數據庫關閉時,FMResultSet也會被自動關閉
FMResultSet *resultSet = [database executeQuery:@"select * from user"];
while ([resultSet next]) {
NSString *name = [resultSet stringForColumn:@"name"];
NSString *gender = [resultSet stringForColumn:@"gender"];
int age = [resultSet intForColumn:@"age"];
NSLog(@"Name:%@,Gender:%@,Age:%d",name,gender,age);
}
[database close];
//這里也不需要release
// [database release];
}
FMResultSet還支持以下方式獲取值:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
//執行條件查詢操作
- (IBAction)queryByConditionBtnTapped:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"];
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
if (![database open]) {
return;
}
FMResultSet *resultSet = [database executeQuery:@"select * from user where name = ?",@"Ryan"];
while ([resultSet next]) {
NSString *name = [resultSet stringForColumn:@"name"];
NSString *gender = [resultSet stringForColumn:@"gender"];
int age = [resultSet intForColumn:@"age"];
NSLog(@"Name:%@,Gender:%@,Age:%d",name,gender,age);
}
[database close];
}

//執行更新操作
- (IBAction)updateBtnTapped:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"];
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
if (![database open]) {
return;
}
//參數必須是NSObject的子類,int,double,bool這種基本類型,需要封裝成對應的包裝類才可以
BOOL update = [database executeUpdate:@"update user set name = ? where age = ?",@"RyanTang",[NSNumber numberWithInt:24]];
if(update){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"更新成功" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
[database close];
}

//執行刪除操作
- (IBAction)deleteBtnTapped:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"];
FMDatabase *database = [FMDatabase databaseWithPath:dbPath];
if (![database open]) {
return;
}
BOOL delete = [database executeUpdate:@"delete from user where name = ?",@"Tang"];
if (delete) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"刪除成功" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
[database close];
}

如果我們的app需要多線程操作數據庫,那么就需要使用FMDatabaseQueue來保證線程安全了。切記不能在多個線程中共同一個FMDatabase對象并且在多個線程中同時使用,這個類本身不是線程安全的,這樣使用會造成數據混亂等問題。
使用FMDatabaseQueue很簡單,首先用一個數據庫文件地址來初使化FMDatabaseQueue,然后就可以將一個閉包(block)傳入inDatabase方法中。在閉包中操作數據庫,而不直接參與FMDatabase的管理。
-(void)executeDBOperation
{
//獲取Document文件夾下的數據庫文件,沒有則創建
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dbPath = [docPath stringByAppendingPathComponent:@"user.db"];
FMDatabaseQueue *databaseQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
[databaseQueue inDatabase:^(FMDatabase *db){
[db executeUpdate:@"insert into user values (?,?,?)",@"Ren",@"Male",[NSNumber numberWithInt:20]];
}];
[databaseQueue close];
}
歡迎關注我的新浪微博和我交流:@唐韌_Ryan
智能推薦
第三方庫之—Glide的使用
Glide的使用 Glide是我使用最久,也是最喜歡的一款第三方圖片加載框架,以前只是使用,也沒有做系統性的總結,現在開始重新整理一遍這些優秀的第三方框架。 Glide官方地址: Glide的相關方法: with:指定了聲明周期 load():加載資源,String/Uri/File/Integer/URL/byte[]/T,或者 loadFromMediaStore(Uri uri) place...
Python學習筆記——Django第三方
目錄 第三方 布署 富文本編輯器 在Admin中使用 自定義使用 顯示 全文檢索 創建引擎及索引 使用 發送郵件 celery 布署 搭建服務器虛擬環境 WSGI uWSGI Nginx 第三方 本次課程中主要介紹一些常用的第三方Django模塊,包括: 富文本編輯器 全文檢索 發送郵件 celery 布署 當項目開發完成后,需要將代碼放到服務器上,這個過程稱為布署,服務器上需要有一個運行代碼的環...
PHP第三方登錄學習筆記
一、OAuth2.0 (一)什么是OAuth 全稱為Open Authorization,即開放式授權。 OAuth協議為用戶資源的授權提供了一個安全的、開放而又簡易的標準。與以往的授權方式不同之處是OAuth的授權不會使第三方觸及到用戶的賬戶信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權,因此OAuth是安全的。 (二)OAuth的工作原理 (三)OAu...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
猜你喜歡
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...