自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

iOS開(kāi)發(fā)中的sqlite數(shù)據(jù)庫(kù)

移動(dòng)開(kāi)發(fā) iOS
本文將詳細(xì)介紹一下iOS開(kāi)發(fā)中sqlite數(shù)據(jù)庫(kù)的原理和使用方法,希望通過(guò)本文的介紹和講解,各位讀者朋友可以進(jìn)一步的對(duì)iOS中的sqlite數(shù)據(jù)庫(kù)有所了解與掌握。

前面寫(xiě)了一篇博文講如何在C#中使用ADO訪問(wèn)各種數(shù)據(jù)庫(kù),在移動(dòng)開(kāi)發(fā)和嵌入式領(lǐng)域也有一個(gè)輕量級(jí)的開(kāi)源關(guān)系型數(shù)據(jù)庫(kù)-sqlite。它的特點(diǎn)是零配置(無(wú)需服務(wù)器),單磁盤(pán)文件存儲(chǔ)數(shù)據(jù)(就像 fopen一樣),平臺(tái)無(wú)關(guān)性,使用起來(lái)簡(jiǎn)單又高效。這些特點(diǎn)讓其非常適合移動(dòng)開(kāi)發(fā)和嵌入式領(lǐng)域。當(dāng)然,sqlite也因其力求簡(jiǎn)單高效,也就限制了它對(duì)并發(fā),海量數(shù)據(jù)的處理。下面,我就再接再厲,來(lái)講講如何在iOS開(kāi)發(fā)中使用sqlite數(shù)據(jù)庫(kù)和第三方封裝庫(kù)FMDB,以及介紹一個(gè)MAC下開(kāi)源的可視化sqlite瀏覽器。

本文源碼:https://github.com/kesalin/iOSSnippet/tree/master/SQLiteDemo

一,在 iOS 中的使用

在 iOS 中 sqlite3 庫(kù)是一套純 C 的接口,因此很方便地就可以在 obj-c 源碼中無(wú)痕使用它,而且其使用方式與用 ADO 方式操作數(shù)據(jù)庫(kù)大同小異-少了創(chuàng)建數(shù)據(jù)庫(kù)鏈接一環(huán)而已(因?yàn)?sqlite 沒(méi)有服務(wù)器的概念也就無(wú)需鏈接了)。

首先,需要引入 libsqlite3.0.dylib:

    然后包含頭文件:

    #import "/usr/include/sqlite3.h"

     

    打開(kāi)或創(chuàng)建數(shù)據(jù)庫(kù)

    1. SQLITE_API int sqlite3_open( 
    2.   const char *filename,   /* Database filename (UTF-8) */ 
    3.   sqlite3 **ppDb          /* OUT: SQLite db handle */ 
    4. ); 

使用示例:(dbPath 為 NSString *)

  1. // open database 
  2. // 
  3. int state = sqlite3_open([dbPath UTF8String], &database); 
  4. if (state == SQLITE_OK) { 
  5.     DLOG(@" >> Succeed to open database. %@", dbPath); 
  6. else { 
  7.     DLOG(@" >> Failed to open database. %@", dbPath); 

關(guān)閉數(shù)據(jù)庫(kù)

  1. SQLITE_API int sqlite3_close(sqlite3 *); 

上面這個(gè)接口將關(guān)閉數(shù)據(jù)庫(kù),如果當(dāng)前還有事務(wù)沒(méi)有提交,會(huì)先執(zhí)行 rollback 操作,然后再關(guān)閉數(shù)據(jù)庫(kù)。

執(zhí)行 sql 語(yǔ)句

  1. SQLITE_API int sqlite3_exec( 
  2.   sqlite3*,                                  /* An open database */ 
  3.   const char *sql,                           /* SQL to be evaluated */ 
  4.   int (*callback)(void*,int,char**,char**),  /* Callback function */ 
  5.   void *,                                    /* 1st argument to callback */ 
  6.   char **errmsg                              /* Error msg written here */ 
  7. ); 

這個(gè)接口是最常用到的,幾乎除了查詢之外的 sql 命令都可以用它來(lái)操作,比如創(chuàng)建表,插入/更新/刪除記錄,創(chuàng)建/提交/回滾事務(wù)等。注意:如果 errmsg 不為 null,那么當(dāng)錯(cuò)誤發(fā)生時(shí), sqlite 就會(huì)為錯(cuò)誤消息分配內(nèi)存,返回給調(diào)用者,調(diào)用者有責(zé)任調(diào)用 sqlite3_free 來(lái)釋放這部分內(nèi)存。為了方便使用,我封裝了一個(gè)簡(jiǎn)單的 obj-c 方法:

  1. - (BOOL)excuteSQLWithCString:(const char *)sqlCmd 
  2.     char * errorMsg; 
  3.     int state = sqlite3_exec(database, sqlCmd, NULL, NULL, &errorMsg); 
  4.     if (state == SQLITE_OK) { 
  5.         DLOG(@" >> Succeed to %@"
  6.              [NSString stringWithCString:sqlCmd encoding:NSUTF8StringEncoding]); 
  7.     } 
  8.     else { 
  9.         DLOG(@" >> Failed to %@. Error: %@"
  10.              [NSString stringWithCString:sqlCmd encoding:NSUTF8StringEncoding], 
  11.              [NSString stringWithCString:errorMsg encoding:NSUTF8StringEncoding]); 
  12.          
  13.         sqlite3_free(errorMsg); 
  14.     } 
  15.      
  16.     return (state == SQLITE_OK); 

下面是創(chuàng)建表以及事務(wù)操作的使用示例:

  1. - (void)createTable 
  2.     if (database == NULL) { 
  3.         DLOG(@" >> Database does not open yet."); 
  4.         return
  5.     } 
  6.     const char * sqlCmd = "create table if not exists customer (id integer primary key autoincrement, name text not null, address text, age integer)";    
  7.     [self excuteSQLWithCString:sqlCmd]; 
  8. - (BOOL)beginTransaction 
  9.     return [self excuteSQLWithCString:"BEGIN EXCLUSIVE TRANSACTION;"]; 
  10. - (BOOL)commit 
  11.     return [self excuteSQLWithCString:"COMMIT TRANSACTION;"];     
  12. - (BOOL)rollback 
  13.     return [self excuteSQLWithCString:"ROLLBACK TRANSACTION;"]; 

很簡(jiǎn)單,不是么?至于插入,更新,刪除示例,請(qǐng)參考如下 sqlCmd:

  1. // insert 
  2.     NSString * sqlCmd = [NSString stringWithFormat:@"insert into customer (name, address, age) values ('%@', '%@', %d)"
  3.                            customer.name, customer.address, customer.age]; 
  4. // update 
  5.     NSString * sqlCmd = [NSString stringWithFormat:@"update customer set address='%@',age=%d where name='%@'"
  6.                          newValue.address, newValue.age, oldValue.name]; 
  7. // delete 
  8.     NSString * sqlCmd = [NSString stringWithFormat:@"delete from customer where name='%@'"
  9.                            customer.name]; 

 

查詢操作

查詢操作稍微負(fù)責(zé)一點(diǎn),需要?jiǎng)?chuàng)建查詢描述(sqlite3_stmt),然后調(diào)用如下接口編譯成字節(jié)程序:

  1. SQLITE_API int sqlite3_prepare_v2( 
  2.   sqlite3 *db,            /* Database handle */ 
  3.   const char *zSql,       /* SQL statement, UTF-8 encoded */ 
  4.   int nByte,              /* Maximum length of zSql in bytes. */ 
  5.   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */ 
  6.   const char **pzTail     /* OUT: Pointer to unused portion of zSql */ 
  7. ); 

注意:這里使用的是 v2 - version 2,這是 sqlite 推薦使用的版本,version 1 僅僅是為了向后兼容而保留著。

然后使用如下接口來(lái)評(píng)估的查詢結(jié)果:

  1. SQLITE_API int sqlite3_step(sqlite3_stmt*); 

如果該接口返回 SQLITE_ROW,表面查詢到了一行記錄,我們就可以以下接口從查詢描述中獲取我們想要的值:

  1. SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); 
  2. SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); 
  3. SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); 
  4. SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); 
  5. SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); 
  6. SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); 
  7. SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); 
  8. SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); 
  9. SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); 
  10. SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); 

最后,需要通過(guò)如下接口釋放先前創(chuàng)建的查詢描述。通常,為了提高查詢效率,可以把常用的查詢描述緩存起來(lái)。

  1. SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); 

下面就來(lái)看一個(gè)具體的使用示例:

  1. - (NSArray *)queryAllCustomers 
  2.     NSMutableArray * array = [[NSMutableArray alloc] init]; 
  3.     const char * sqlCmd = "select name, address, age from customer"
  4.     sqlite3_stmt * statement; 
  5.     int state = sqlite3_prepare_v2(database, sqlCmd, -1, &statement, nil); 
  6.     if (state == SQLITE_OK) { 
  7.         DLOG(@" >> Succeed to prepare statement. %@"
  8.              [NSString stringWithCString:sqlCmd encoding:NSUTF8StringEncoding]); 
  9.     } 
  10.     NSInteger index = 0; 
  11.     while (sqlite3_step(statement) == SQLITE_ROW) { 
  12.         // get raw data from statement 
  13.         // 
  14.         char * cstrName = (char *)sqlite3_column_text(statement, 0); 
  15.         char * cstrAddress = (char *)sqlite3_column_text(statement, 1); 
  16.         int age = sqlite3_column_int(statement, 2); 
  17.         NSString * name = [NSString stringWithCString:cstrName encoding:NSUTF8StringEncoding]; 
  18.         NSString * address = [NSString stringWithCString:cstrAddress encoding:NSUTF8StringEncoding]; 
  19.         KSCustomer * customer = [[KSCustomer alloc] 
  20.                                  initWith:name 
  21.                                  address:address 
  22.                                  age:age]; 
  23.         [array addObject:customer]; 
  24.         DLOG(@"   >> Record %d : %@ %@ %d", index++, name, address, age); 
  25.     } 
  26.     sqlite3_finalize(statement); 
  27.     DLOG(@" >> Query %d records.", [array count]); 
  28.     return array; 

二,MAC 下查看 sqlite db 文件的工具

MAC 下有一款不錯(cuò)的開(kāi)源可視化 sqlite db 瀏覽器:SQLite Database Browser,你可以從以下鏈接獲取:

http://sourceforge.net/projects/sqlitebrowser/

該軟件運(yùn)行界面如下:

三,封裝 sqlite 的第三方庫(kù) FMDB

在 iOS 中直接使用 sqlite 原生 C 接口還是不那么方便,因此催生了第三方的 iOS 版封裝庫(kù),其中使用比較廣泛又輕量級(jí)的就是 FMDB(https://github.com/ccgus/fmdb),目前該庫(kù)只有六個(gè)文件,不超過(guò)2000行代碼。

使用也是非常簡(jiǎn)單,在工程中包含這六個(gè)文件:

然后包含頭文件:

  1. #import "FMDatabase.h" 
  2. #import "FMResultSet.h" 
  3. #import "FMDatabaseAdditions.h" 

就可以使用該庫(kù)了:

  1.  // Create database 
  2.     // 
  3.     NSString * path  = [UIHUtilities configPathFor:kDatabaseFile]; 
  4.     FMDatabase db  = [[FMDatabase databaseWithPath:path] retain]; 
  5.     if (![db open]) 
  6.     {   
  7.         DLog(@" >> Error: Failed to open database at %@", path); 
  8.     } 
  9. #if DEBUG 
  10.     db.traceExecution = TRUE; 
  11. #endif 
  12.     // Create tables 
  13.     // 
  14.     [db executeUpdate:@"CREATE TABLE Image (studyUid text, patientId text, seriesUid text, SOPUid text, contentDate text, modality text, patientPosition text, filepath text, thumbnailPath text)"]; 
  15.     // insert 
  16.     // 
  17.     BOOL retValue = [db executeUpdate:@"INSERT INTO Image (studyUid, patientId, seriesUid, SOPUid, contentDate, patientPosition, modality, filepath, thumbnailPath) VALUES (?,?,?,?,?,?,?,?,?)", image.studyUid, image.patientId, image.seriesUid, image.SOPUid, image.contentDate, image.patientPosition, image.modality, image.filepath, image.thumbnailPath];    
  18.     if (!retValue) 
  19.         DLog(@" >> Error: Database failed to insert image %@", image); 
  20.     // query 
  21.     // 
  22.     FMResultSet *rs = [db executeQuery:@"SELECT * FROM Image WHERE SOPUid = ?", SOPUid]; 
  23.     if ([rs next]) 
  24.     { 
  25.          .... 
  26.     } 
  27.     // query count 
  28.     // 
  29.     NSInteger count = 0; 
  30.     FMResultSet *rs = [db executeQuery:@"SELECT COUNT(*) FROM Image WHERE seriesUid = ?", seriesUid]; 
  31.     if ([rs next]) { 
  32.         count = [rs intForColumnIndex:0]; 
  33.     } 
  34.     // delete 
  35.     // 
  36.     retValue = [db executeUpdate:@"DELETE FROM Image WHERE seriesUid = ?", seriesUid]; 
  37.     if (!retValue) 
  38.         DLog(@" >> Error: Database failed to delete image by seriesUid %@", seriesUid); 
  39.     // release database 
  40.     // 
  41.     [db release];

怎么樣,經(jīng)過(guò)本文的介紹您是否對(duì)iOS開(kāi)發(fā)中的sqlite數(shù)據(jù)庫(kù)有了一定的理解和掌握?

責(zé)任編輯:閆佳明 來(lái)源: cnblogs
相關(guān)推薦

2013-03-27 09:47:01

Android開(kāi)發(fā)SQAndroid SDK

2011-08-02 16:16:08

iPhone開(kāi)發(fā) SQLite 數(shù)據(jù)庫(kù)

2011-08-30 14:15:34

QTSQLite數(shù)據(jù)庫(kù)

2013-01-06 09:52:43

SQLite

2013-04-09 16:04:06

iOS開(kāi)發(fā)SQLite知識(shí)總結(jié)

2011-07-27 10:16:41

iPhone SQLite 數(shù)據(jù)庫(kù)

2011-08-22 16:08:46

IOS開(kāi)發(fā)數(shù)據(jù)庫(kù)

2024-09-20 18:02:42

C#數(shù)據(jù)庫(kù)SQLite

2017-07-12 09:20:42

SQLite數(shù)據(jù)庫(kù)移植

2011-07-20 12:34:49

SQLite數(shù)據(jù)庫(kù)約束

2019-08-15 07:00:54

SQLite數(shù)據(jù)庫(kù)內(nèi)存數(shù)據(jù)庫(kù)

2011-08-24 13:49:45

Access數(shù)據(jù)庫(kù)轉(zhuǎn)化

2011-08-22 15:43:08

IOS開(kāi)發(fā)數(shù)據(jù)庫(kù)

2011-07-07 16:42:38

iPhone Sqlite3 數(shù)據(jù)庫(kù)

2011-08-04 18:00:47

SQLite數(shù)據(jù)庫(kù)批量數(shù)據(jù)

2009-09-14 13:57:37

SQLite數(shù)據(jù)庫(kù)開(kāi)發(fā)

2024-10-28 16:31:03

2011-07-12 15:22:04

SQLite數(shù)據(jù)庫(kù)

2011-03-25 13:34:20

SQLite數(shù)據(jù)庫(kù)

2011-07-04 18:02:29

QT Sqlite 數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)