導(dǎo)入SQLLite library并引入頭文件
libsqlite3.dylib本身是個鏈接,在這里它指向libsqlite3.0.dylib。也就是說在這里你添加libsqlite3.dylib和添加libsqlite3.0.dylib其實是添加了同一個文件,沒有區(qū)別,那為什么要添加libsqlite3.dylib呢?原因在于libsqlite3.dylib總是指向最新的sqlite3動態(tài)庫,也就是說如果出現(xiàn)了新的動態(tài)庫(如:libsqlite3.1.dylib)那libsqlite3.dylib將指向這個新的動態(tài)庫(libsqlite3.1.dylib)而不在是libsqlite3.0.dylib了!所以建議還是要添加libsqlite3.dylib。
注:
On Mac OS X, frameworks are just libraries, packed into a bundle. Within the
bundle you will find an actual dynamic library (libWhatever.dylib). The difference between a bare library and the framework on Mac is that a framework can contain multiple different versions of the library. It can contain extra resources (images, localized
strings, XML data files, UI objects, etc.) and unless the framework is released to public, it usually contains the necessary .h files you need to use the library.
A
library is just that, "a library". It is a collection of objects/functions/methods (depending on your language) and your application "links" against it and thus can use the objects/functions/methods. It is basically a file containing re-usable code that can
usually be shared among multiple applications (you don't have to write the same code over and over again).
打開數(shù)據(jù)庫鏈接sqlite3_open用法
原型:
- int sqlite3_open(
- const char *filename, <span style="color:#009900;"></span>
- sqlite3 **ppDb <span style="color:#009900;"></span>
- );
用這個函數(shù)開始數(shù)據(jù)庫操作。需要傳入兩個參數(shù),一是數(shù)據(jù)庫文件名,比如:比如:E:/test.db. 在ios中可能是:
- NSArray * documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString * dbPath = [[documentPath objectAtIndex:0] stringByAppendingPathComponent:@“test.db”];
文件名不需要一定存在,如果此文件不存在,sqlite會自動建立它。如果它存在,就嘗試把它當數(shù)據(jù)庫文件來打開。二是sqlite3**,即前面提到的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。這個結(jié)構(gòu)底層細節(jié)如何,你不要管它。 函數(shù)返回值表示操作是否正確,如果是SQLITE_OK則表示操作正常。相關(guān)的返回值sqlite定義了一些宏。具體這些宏的含義可以參考sqlite3.h 文件。里面有詳細定義(順便說一下,sqlite3 的代碼注釋率自稱是非常高的,實際上也的確很高。只要你會看英文,sqlite
可以讓你學(xué)到不少東西)。
關(guān)閉數(shù)據(jù)庫鏈接sqlite3_close用法
原型:
- int sqlite3_close(sqlite3 *ppDb);
ppDb為剛才使用sqlite3_open打開的數(shù)據(jù)庫鏈接
執(zhí)行sql操作sqlite3_exec用法
原型:
- int sqlite3_exec(
- sqlite3* ppDb, <span style="color:#009900;"></span>
- const char *sql, <span style="color:#009900;"></span>
- int (*callback)(void*,int,char**,char**), <span style="color:#009900;"></span>
- void *, <span style="color:#009900;"></span>
- char **errmsg <span style="color:#009900;"> </span>
- );
這就是執(zhí)行一條sql 語句的函數(shù)。 第1個參數(shù)不再說了,是前面open函數(shù)得到的指針。第2個參數(shù)constchar*sql是一條sql 語句,以\0結(jié)尾。 第3個參數(shù)sqlite3_callback 是回調(diào),當這條語句執(zhí)行之后,sqlite3會去調(diào)用你提供的這個函數(shù)。 第4個參數(shù)void*是你所提供的指針,你可以傳遞任何一個指針參數(shù)到這里,這個參數(shù)最終會傳到回調(diào)函數(shù)里面,如果不需要傳遞指針給回調(diào)函數(shù),可以填NULL。等下我們再看回調(diào)函數(shù)的寫法,以及這個參數(shù)的使用。
第5個參數(shù)char** errmsg 是錯誤信息。注意是指針的指針。sqlite3里面有很多固定的錯誤信息。執(zhí)行sqlite3_exec 之后,執(zhí)行失敗時可以查閱這個指針(直接cout<<errmsg得到一串字符串信息,這串信息告訴你錯在什么地方。sqlite3_exec函數(shù)通過修改你傳入的指針的指針,把你提供的指針指向錯誤提示信息,這樣sqlite3_exec函數(shù)外面就可以通過這個char*得到具體錯誤提示。
說明:通常,sqlite3_callback 和它后面的void*這兩個位置都可以填NULL。填NULL表示你不需要回調(diào)。比如你做insert 操作,做delete操作,就沒有必要使用回調(diào)。而當你做select 時,就要使用回調(diào),因為sqlite3 把數(shù)據(jù)查出來,得通過回調(diào)告訴你查出了什么數(shù)據(jù)。
exec 的回調(diào)
typedef int(*sqlite3_callback)(void*,int,char**,char**); 你的回調(diào)函數(shù)必須定義成上面這個函數(shù)的類型。下面給個簡單的例子: //sqlite3的回調(diào)函數(shù) //sqlite 每查到一條記錄,就調(diào)用一次這個回調(diào) int LoadMyInfo(void* para, int n_column, char** column_value, char** column_name);
//para是你在sqlite3_exec 里傳入的void*參數(shù)通過para參數(shù),你可以傳入一些特殊的指針(比如類指針、結(jié)構(gòu)指針), 然后在這里面強制轉(zhuǎn)換成對應(yīng)的類型(這里面是void*類型,必須強制轉(zhuǎn)換成你的類型才可用)。然后操作這些數(shù)據(jù)
//n_column是這一條記錄有多少個字段(即這條記錄有多少列)
//char** column_value 是個關(guān)鍵值,查出來的數(shù)據(jù)都保存在這里,它實際上是個1維數(shù)組(不要以為是2維數(shù)組), 每一個元素都是一個char*值,是一個字段內(nèi)容(用字符串來表示,以\0結(jié)尾)
//char** column_name 跟column_value是對應(yīng)的,表示這個字段的字段名稱
實例:
- 1 #include <iostream>
- 2 using namespace std;
- 3 #include "sqlite/sqlite3.h"
- 4 int callback(void*,int,char**,char**);
- 5 int main()
- 6 {
- 7 sqlite3* db;
- 8 int nResult = sqlite3_open("test.db",&db);
- 9 if (nResult != SQLITE_OK)
- 10 {
- 11 cout<<"打開數(shù)據(jù)庫失?。?<<sqlite3_errmsg(db)<<endl;
- 12 return 0;
- 13 }
- 14 else
- 15 {
- 16 cout<<"數(shù)據(jù)庫打開成功"<<endl;
- 17 }
- 18
- 19 char* errmsg;
- 20
- 21 nResult = sqlite3_exec(db,"create table MyTable(id integer primary key autoincrement,name varchar(100))",NULL,NULL,&errmsg);
- 22 if (nResult != SQLITE_OK)
- 23 {
- 24 sqlite3_close(db);
- 25 cout<<errmsg;
- 26 sqlite3_free(errmsg);
- 27 return 0;
- 28 }
- 29 string strSql;
- 30 strSql+="begin;\n";
- 31 for (int i=0;i<100;i++)
- 32 {
- 33 strSql+="insert into MyTable values(null,'heh');\n";
- 34 }
- 35 strSql+="commit;";
- 36
- 37
- 38 nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg);
- 39
- 40 if (nResult != SQLITE_OK)
- 41 {
- 42 sqlite3_close(db);
- 43 cout<<errmsg<<endl;
- 44 sqlite3_free(errmsg);
- 45 return 0;
- 46 }
- 47
- 48 strSql = "select * from MyTable";
- 49 nResult = sqlite3_exec(db,strSql.c_str(),callback,NULL,&errmsg);
- 50 if (nResult != SQLITE_OK)
- 51 {
- 52 sqlite3_close(db);
- 53 cout<<errmsg<<endl;
- 54 sqlite3_free(errmsg);
- 55 return 0;
- 56 }
- 57
- 58 sqlite3_close(db);
- 59 return 0;
- 60 }
- 61
- 62 int callback(void* ,int nCount,char** pValue,char** pName)
- 63 {
- 64 string s;
- 65 for(int i=0;i<nCount;i++)
- 66 {
- 67 s+=pName[i];
- 68 s+=":";
- 69 s+=pValue[i];
- 70 s+="\n";
- 71 }
- 72 cout<<s<<endl;
- 73 return 0;
- 74 }