Cocos2d-x數據持久化-查詢數據

數據查詢通常會帶有查詢條件,這可使用SQL語句的where子句實現,可是在程序中須要動態綁定參數給where子句。查詢數據的具體操做步驟以下所示。
(1) 使用sqlite3_open函數打開數據庫。
(2) 使用sqlite3_prepare_v2函數預處理SQL語句。
(3) 使用sqlite3_bind_text函數綁定參數。
(4) 使用sqlite3_step函數執行SQL語句,遍歷結果集。
(5) 使用sqlite3_column_text等函數提取字段數據。 
(6) 使用sqlite3_finalize和sqlite3_close函數釋放資源。


NoteDAO.cpp中的NoteDAO::findById是按照主鍵查詢數據函數,相關代碼以下:
html

[html] view plaincopy在CODE上查看代碼片派生到個人代碼片sql

  1. ValueMap NoteDAO::findById(string pDate)  數據庫

  2. {  微信

  3.     //初始化數據庫  函數

  4.     initDB();  網站

  5.     sqlite3* dbNULL;  spa

  6.     ValueMap dict ;  .net

  7.   

  8.   

  9.     string path = dbDirectoryFile();  指針

  10.   

  11.   

  12.     if (sqlite3_open(path.c_str(), &db) != SQLITE_OK) {                             ①  code

  13.         sqlite3_close(db);  

  14.         CCASSERT(false, "DB open failure.");  

  15.     } else {  

  16.         string qsql = "SELECT cdate,content FROM Note where cdate =?";  

  17.         sqlite3_stmt *statement;  

  18.         //預處理過程  

  19.         if (sqlite3_prepare_v2(db, qsql.c_str(), -1, &statement, NULL) == SQLITE_OK) {      ②  

  20.   

  21.   

  22.             //綁定參數開始  

  23.             sqlite3_bind_text(statement, 1, pDate.c_str(), -1, NULL);                       ③  

  24.   

  25.   

  26.             //執行  

  27.             if (sqlite3_step(statement) == SQLITE_ROW) {                            ④  

  28.   

  29.   

  30.                 char *cdate = (char *)sqlite3_column_text(statement, 0);                    ⑤  

  31.                 char *content = (char *)sqlite3_column_text(statement, 1);  

  32.   

  33.   

  34.                 dict["date"] = Value(cdate);                                          

  35.                 dict["content"] = Value(content);                                     

  36.             }  

  37.         }  

  38.         sqlite3_finalize(statement);                                            ⑥  

  39.         sqlite3_close(db);                                                  ⑦  

  40.     }  

  41.     return dict;  

  42. }  



該函數執行了6個步驟,其中第(1)個步驟如代碼第①行所示,它與建立數據庫的第一個步驟同樣,這裏就再也不介紹了。
第(2)個步驟如代碼第②行所示,語句sqlite3_prepare_v2(db, qsql.c_str(), -1, &statement, NULL)是預處理SQL語句。預處理的目的是將SQL編譯成二進制代碼,提升SQL語句的執行速度。sqlite3_prepare_v2函數的第三個參數表示SQL字符串的長度,-1表示所有SQL字符串。第四個參數是sqlite3_stmt指針的地址,它是語句對象,經過語句對象能夠執行SQL語句,第五個參數是SQL語句沒有執行的部分語句。 
第(3)個步驟如代碼第③行所示,語句sqlite3_bind_text(statement, 1, pDate.c_str(), -1, NULL)是綁定SQL語句的參數,其中第一個參數是statement指針,第二個參數爲序號(從1開始),第三個參數爲字符串值,第四個參數爲字符串長度,第五個參數爲一個函數指針。若是SQL語句中帶有問號,則這個問號(它是佔位符)就是要綁定的參數,示例代碼以下所示:
string qsql = "SELECT cdate,content FROM Note where cdate =?";
第(4)個步驟爲使用sqlite3_step(statement)執行SQL語句,如代碼第④行所示。若是sqlite3_step函數返回int類型(即等於SQLITE_ROW),則說明還要其它行數據沒有遍歷。
第(5)個步驟爲提取字段數據,如代碼第⑤行所示,它使用sqlite3_column_text(statement, 0)函數讀取字符串類型的字段。須要說明的是,sqlite3_column_text函數的第二個參數用於指定select字段的索引(從0開始)。讀取字段函數的選擇與字段類型有關係,SQLite3中相似的經常使用函數還有: 
sqlite3_column_blob()
sqlite3_column_double()
sqlite3_column_int()
sqlite3_column_int64()
sqlite3_column_text()
sqlite3_column_text16()
關於其它API,讀者能夠參考http://www.sqlite.org/cintro.html。
第(6)個步驟是釋放資源,與建立數據庫過程不一樣。使用sqlite3_close函數關閉數據庫(見第⑦行)以前,還要使用sqlite3_finalize函數釋放語句對象statement,見代碼第⑥行所示。
NoteDAO.cpp中的NoteDAO::findAll()是查詢全部數據函數,相關代碼以下:
ValueVector NoteDAO::findAll()

[html] view plaincopy在CODE上查看代碼片派生到個人代碼片

  1. {  

  2.     //初始化數據庫  

  3.     initDB();  

  4.     sqlite3* dbNULL;  

  5.   

  6.   

  7.     string path = dbDirectoryFile();  

  8.     ValueVector listData;  

  9.   

  10.   

  11.     if (sqlite3_open(path.c_str(), &db) != SQLITE_OK) {  

  12.         sqlite3_close(db);  

  13.         CCASSERT(false, "DB open failure.");  

  14.     } else {  

  15.         string qsql = "SELECT cdate,content FROM Note";  

  16.         sqlite3_stmt *statement;  

  17.         //預處理過程  

  18.         if (sqlite3_prepare_v2(db, qsql.c_str(), -1, &statement, NULL) == SQLITE_OK) {  

  19.             //執行  

  20.             while (sqlite3_step(statement) == SQLITE_ROW) {  

  21.   

  22.   

  23.                 char *cdate = (char *)sqlite3_column_text(statement, 0);  

  24.                 char *content = (char *)sqlite3_column_text(statement, 1);  

  25.   

  26.   

  27.                 ValueMap dict ;  

  28.                 dict["date"] = Value(cdate);  

  29.                 dict["content"] = Value(content);  

  30.   

  31.   

  32.                 listData.push_back(Value(dict));  

  33.             }  

  34.         }  

  35.         sqlite3_finalize(statement);  

  36.         sqlite3_close(db);  

  37.     }  

  38.     return listData;  

  39. }  


查詢全部數據函數與按照主鍵查詢數據函數相似,區別在於本函數沒有查詢條件不須要綁定參數。遍歷的時候使用while循環語句,不是if語句:

[html] view plaincopy在CODE上查看代碼片派生到個人代碼片

  1. while (sqlite3_step(statement) == SQLITE_ROW) {  

  2.     ……  

  3. }  





爲了可以調用NoteDAO中查詢函數findAll (),咱們須要在HelloWorldScene場景中調用。HelloWorldScene.cpp主要代碼以下:

[html] view plaincopy在CODE上查看代碼片派生到個人代碼片

  1. void HelloWorld::OnClickMenu5(Ref* pSender)  

  2. {  

  3.     auto arry = NoteDAO::findAll();                                         ①  

  4.   

  5.   

  6.     for (auto& v: arry)  

  7.     {  

  8.         log("-----------------");  

  9.         ValueMap row = v.asValueMap();                                      ②  

  10.         string date = row["date"].asString();                                       ③  

  11.         string content = row["content"].asString();                                 ④  

  12.   

  13.   

  14.         log("===>date: : %s", date.c_str());  

  15.         log("===>content: : %s", content.c_str());  

  16.     }  

  17.   

  18.   

  19. }  



HelloWorld::OnClickMenu5函數是玩家點擊Read Data菜單時候回調的函數。其中代碼第①行是調用NoteDAO中查詢全部函數findAll (),第②行代碼是把從列表中取出的元素v,轉換爲ValueMap字典類型。第③行代碼是從字典中取值date數據。第④行代碼是從字典中取值content數據。


更多內容請關注國內第一本Cocos2d-x 3.2版本圖書《Cocos2d-x實戰:C++卷》

本書交流討論網站:http://www.cocoagame.net
更多精彩視頻課程請關注智捷課堂Cocos課程:http://v.51work6.com

歡迎加入Cocos2d-x技術討論羣:257760386

歡迎關注智捷iOS課堂微信公共平臺

相關文章
相關標籤/搜索