SQLite3數(shù)據(jù)庫(kù)Native
C++封裝類(lèi)(Unicode)CppSQLite3U的初步認(rèn)識(shí)與使用 by斜風(fēng)細(xì)雨QQ:253786989 2012-02-12
(1)
http://www./cvstrac/wiki?p=SqliteWrappers
從上面的網(wǎng)址可以找到對(duì)SQLite數(shù)據(jù)庫(kù)的C API的各種語(yǔ)言的封裝。包括c、c++、vb、c#.net、delphi、Lisp、D、Java、Javascript、Objective-C、Perl、PHP、Python、Ruby、Lua、Fortran等等。從這也可以看出SQLite數(shù)據(jù)庫(kù)作為本地?cái)?shù)據(jù)存儲(chǔ)工具而得到的廣泛應(yīng)用。單單是“C++
Wrappers”也有幾十種,常見(jiàn)的如:easySQLite、SQLite++、CppSQLite、CppSQLiteU等等。因?yàn)槲彝ǔJ窃?span style="font-family:Courier New">Windows CE嵌入式操作系統(tǒng)上開(kāi)發(fā)APP,而Windows
CE操作系統(tǒng)只支持Unicode字符集,所以今天要學(xué)習(xí)和測(cè)試的是Unicode版“C++ Wrappers”:CppSQLiteU。
(2)
因?yàn)槭窃?span style="font-family:Courier New">Windows CE操作系統(tǒng)上使用SQLite,所以在使用CppSQLiteU之前,要先編譯針對(duì)Windows
CE平臺(tái)的SQLite3 DLL。這一步省了,我直接借用了別人已經(jīng)編譯好的。
(3)
下面是一個(gè)簡(jiǎn)單測(cè)試示例,主要是利用class CppSQLite3DB新建數(shù)據(jù)庫(kù)、創(chuàng)建表、插入刪除更新記錄、使用事務(wù)、查詢記錄等等。
- #define SQLITE3_FILE_NAME TEXT("sqlite.db3")
-
- // 獲取程序當(dāng)前路徑
- void GetCurrentDirectory(CString &szPath)
- {
- TCHAR buf[256] = {0};
- GetModuleFileName(NULL, buf, sizeof(buf)/sizeof(TCHAR));
- szPath = buf;
- szPath = szPath.Left(szPath.ReverseFind('\\') + 1);
- }
-
- CString strDbPath;
- GetCurrentDirectory(strDbPath);
- strDbPath += SQLITE3_FILE_NAME;
-
- CppSQLite3DB db;
-
- try
- {
- // 打開(kāi)或新建一個(gè)數(shù)據(jù)庫(kù)
- db.open(strDbPath);
-
- // 判斷表名是否已經(jīng)存在
- if(!db.tableExists(TEXT("Customers")))
- {
- // 不存在,新建表Customers
- db.execDML(TEXT("CREATE TABLE Customers(cust_name varchar(50) NOT NULL PRIMARY KEY, cust_address varchar(50));"));
- }
-
- // 插入1條記錄
- db.execDML(TEXT("INSERT INTO Customers VALUES('Village Toys', '200 Maple Lane');"));
- // 插入1條記錄
- db.execDML(TEXT("INSERT INTO Customers VALUES('Kids Place', '333 South Lake Drive');"));
-
- // 刪除1條記錄
- db.execDML(TEXT("DELETE FROM Customers WHERE cust_name = 'Village Toys';"));
-
- // 使用顯示事務(wù)插入10條記錄
- TCHAR buf[256] = {0};
- db.execDML(TEXT("BEGIN TRANSACTION;"));
- for (int i = 0; i < 10; ++i)
- {
- memset(buf, 0, sizeof(buf));
- wsprintf(buf, TEXT("INSERT INTO Customers VALUES ('Fun%dALL', '%d Sunny Place');"), i, i);
- db.execDML(buf);
- }
- db.execDML(TEXT("COMMIT TRANSACTION;"));
-
- // 更新1條記錄
- db.execDML(TEXT("UPDATE Customers SET cust_address = '4545 53rd Street' WHERE cust_name = 'Fun0ALL';"));
-
- // 獲取總記錄條數(shù)
- int nCount = db.execScalar(TEXT("SELECT COUNT(*) FROM Customers;"));
- TCHAR szCount[50] = {0};
- memset(szCount, 0, sizeof(szCount));
- wsprintf(szCount, TEXT("Record count: %d."), nCount);
- AfxMessageBox(szCount);
-
- // 獲取每一條記錄
- CppSQLite3Query q = db.execQuery(TEXT("SELECT * FROM Customers;"));
- while (!q.eof())
- {
- AfxMessageBox(q.fieldValue(0));
- q.nextRow();
- }
-
- // 銷(xiāo)毀語(yǔ)句
- q.finalize();
-
- // 關(guān)閉數(shù)據(jù)庫(kù)
- db.close();
- AfxMessageBox(TEXT("測(cè)試完成!"));
- }
- catch(CppSQLite3Exception ex)
- {
- AfxMessageBox(ex.errorMessage());
- }
(4)
CppSQLite3U封裝了4個(gè)類(lèi):CppSQLite3Exception、CppSQLite3DB、CppSQLite3Statement、CppSQLite3Query。
a) CppSQLite3Exception用于捕捉異常,errorCode以整數(shù)類(lèi)形返回錯(cuò)誤碼,errorMessage以Unicode字符串類(lèi)型返回錯(cuò)誤碼。
- class CppSQLite3Exception
- {
- public:
- … …
- const int errorCode() { return mnErrCode; }
- LPCTSTR errorMessage() { return mpszErrMess; }
- static LPCTSTR errorCodeAsString(int nErrCode);
- … …
- };
通常用法如:
- try
- {
- … …
- }
- catch(CppSQLite3Exception ex)
- {
-
- AfxMessageBox(ex.errorMessage());
- }
b) CppSQLite3DB用于新建數(shù)據(jù)庫(kù),打開(kāi)關(guān)閉數(shù)據(jù)庫(kù)連接,執(zhí)行DML、DDL,檢索數(shù)據(jù)等。如:open打開(kāi)數(shù)據(jù)庫(kù)連接,close關(guān)閉數(shù)據(jù)庫(kù)連接,tableExists檢查某表是否存在,execDML執(zhí)行SQL命令,execQuery檢索記錄,setBusyTimeout設(shè)置SQLite內(nèi)部的busy
handler的超時(shí)時(shí)間,SQLiteVersion返回SQLite版本。
- class CppSQLite3DB
- {
- public:
- … …
- void open(LPCTSTR szFile);
- void close();
- bool tableExists(LPCTSTR szTable);
- int execDML(LPCTSTR szSQL);
- CppSQLite3Query execQuery(LPCTSTR szSQL);
- int execScalar(LPCTSTR szSQL);
- CString execScalarStr(LPCTSTR szSQL);
- CppSQLite3Statement compileStatement(LPCTSTR szSQL);
- sqlite_int64 lastRowId();
- void interrupt() { sqlite3_interrupt(mpDB); }
- void setBusyTimeout(int nMillisecs);
- static const char* SQLiteVersion() { return SQLITE_VERSION; }
- … …
- };
c) CppSQLite3Statement也可以執(zhí)行SQL命令,它最大的特點(diǎn)是支持參數(shù)綁定。對(duì)于參數(shù)綁定的用處,參考“SQlite數(shù)據(jù)庫(kù)的C編程接口(四)
綁定參數(shù)(Bound Parameters) ——《Using SQlite》讀書(shū)筆記”學(xué)習(xí)。該類(lèi)導(dǎo)出的接口函數(shù)中,bind用于給SQL語(yǔ)句中的參數(shù)綁定指定的值,reset函數(shù)用于重置SQL語(yǔ)句,finalize用于銷(xiāo)毀語(yǔ)句。
- class CppSQLite3Statement
- {
- public:
- … …
- CppSQLite3Statement& operator=(const CppSQLite3Statement& rStatement);
- int execDML();
- CppSQLite3Query execQuery();
- void bind(int nParam, LPCTSTR szValue);
- void bind(int nParam, const int nValue);
- void bind(int nParam, const double dwValue);
- void bind(int nParam, const unsigned char* blobValue, int nLen);
- void bindNull(int nParam);
- void reset();
- void finalize();
- … …
- };
用法如:
- try
- {
- CppSQLite3DB db;
- db.execDML("CREATE TABLE emp(empno int, empname char(20));");
- db.execDML("BEGIN TRANSACTION;");
- CppSQLite3Statement stmt = db.compileStatement("INSERT INTO emp VALUES (:empno, : empname);");
- for (i = 0; i < nRowsToCreate; ++i)
- {
- char buf[16];
- sprintf(buf, "EmpName%06d", i);
- stmt.bind(":empno", i);
- stmt.bind(":empname ", buf);
- stmt.execDML();
- stmt.reset();
- }
- db.execDML("COMMIT TRANSACTION; ");
- }
- catch (CppSQLite3Exception& e)
- {
- cerr << e.errorCode() << ":" << e.errorMessage() << endl;
- }
d) CppSQLite3Query用于檢索記錄并讀出結(jié)果。它導(dǎo)出的public接口函數(shù)大多都是SQLite3的C
API _sqlite3_column_xxx函數(shù)的封裝,通過(guò)該API函數(shù)讀取結(jié)果集中某一行的某一列。nextRow函數(shù)用于檢索下一行,eof用于判斷是否到結(jié)果集的結(jié)尾。
- class CppSQLite3Query
- {
- public:
- … ….
- int numFields();
- int fieldIndex(LPCTSTR szField);
- LPCTSTR fieldName(int nCol);
- LPCTSTR fieldDeclType(int nCol);
- int fieldDataType(int nCol);
- LPCTSTR fieldValue(int nField);
- LPCTSTR fieldValue(LPCTSTR szField);
- int getIntField(int nField, int nNullValue=0);
- int getIntField(LPCTSTR szField, int nNullValue=0);
- double getFloatField(int nField, double fNullValue=0.0);
- double getFloatField(LPCTSTR szField, double fNullValue=0.0);
- LPCTSTR getStringField(int nField, LPCTSTR szNullValue=_T(""));
- LPCTSTR getStringField(LPCTSTR szField, LPCTSTR szNullValue=_T(""));
- const unsigned char* getBlobField(int nField, int& nLen);
- const unsigned char* getBlobField(LPCTSTR szField, int& nLen);
- bool fieldIsNull(int nField);
- bool fieldIsNull(LPCTSTR szField);
- bool eof();
- void nextRow();
- void finalize();
- … …
- };
SQLite3數(shù)據(jù)庫(kù)Native
C++封裝類(lèi)(Unicode)CppSQLite3U的初步認(rèn)識(shí)與使用 by斜風(fēng)細(xì)雨QQ:253786989 2012-02-12
|