mysql 获取结果_【原创】7. MYSQL++中的查询结果获取(各种Result类型)
在本節中,我將首先介紹MYSQL++中的查詢的幾個簡單例子用法,然后看一下mysqlpp::Query中的幾個與查詢相關的方法原型(重點關注返回值),最后對幾個關鍵類型進行解釋。
1. MYSQL++的查詢實例
下面的兩個例子分別是STORE(所有數據一次性從服務器拉到本地緩存)和USE(將數據一條一條從服務器拉到本地)的使用方式,其中STORE內部實質就是mysql_store(
),而USE實質就是調用了mysql_use( )。
說明,下面的例子雖然使用的都是最為基本的查詢過程(即沒有使用template
sql或者SSQLS),但是這個并不影響我們的討論,因為遍歷結果集的過程是一致的。
STOREmysqlpp::Query query = conn.query("select item from stock");
mysqlpp::StoreQueryResult res = query.store();
mysqlpp::StoreQueryResult::const_iterator it;
for (it = res.begin(); it != res.end(); ++it)
{
mysqlpp::Row row = *it;
// 第一列 row[0]
// 第二列 row[1]
}
USEmysqlpp::Query query = conn.query("select * from stock");
mysqlpp::UseQueryResult res = query.use();
while (mysqlpp::Row row = res.fetch_row())
{
row["item"];
row["num"];
}
// Check for error:
// can‘t distinguish "end of results" and
// error cases in return from fetch_row() otherwise
if (conn.errnum())
{
cout << "Error in fetch_row";
}
從上面的兩個例子中我們大致可以看出來,整個結果集的查詢過程就是針對相匹配的Result類型,找到ROW,然后逐行或者跳躍著查找。
2.
Result相關類型的使用場合
首先讓我們回顧mysqlpp::Query中提到的幾個方法,以及他們的返回值。以下部分內容直接摘自關于mysqlpp::Query的介紹的內容。
為了講述方便,我們先來看一下在result.h(Declares classes for holding information about SQL
query)中所定義的各種類型的關系。這幾個類型后面會仔細說明。
1)bool mysqlpp::Query::exec(const std::string& str);
這里返回的是bool,表示的是“語句是否執行成功”,我認為適合于那種update,
delete,insert,且都不關心有多少rows被touch的情況。
2)SimpleResult mysqlpp::Query::execute();
這里的SimpleResult正如其名,其中只有如下信息
the last value used for an AUTO_INCREMENT field
(ulonglong insert_id() const)
the number of rows affected by the query(ulonglong rows( ) const)
any additional information about the query returned by the server(const
char* info( ) const)
3)UseQueryResult mysqlpp::Query::use();
由于use的語義類似于使用游標,也就是支持一行一行地拉出內容,所以UseQueryResult 也就自然而然地支持一些關于fetch
row的功能。
4)StoreQueryResult mysqlpp::Query::store();
StoreQueryResult它本身就是從vector繼承而來,所以它就是vector。所以用戶程序可以直接使用下標的形式來獲取所有的ROW。這也就是說在這個store之后,所有的ROW的內容都在了這個vecor里面了。
3.
Result相關類型解析
與Result相關的類型主要集中在result.h和result.cpp。
1) SimpleResult
這個類型非常簡單,是一個比較單純的類型,并沒有父類。主要的成員變量有3個,分別是
// last value used for an AUTO_INCREMENT field
ulonglong insert_id_;
// the number of rows affected by the query
ulonglong rows_;
// any additional information about the query returned by the server
std::string info_;
成員方法也比較單純,就是對上述幾個字段的GET,構造函數就是對上述幾個字段的SET。
以SimpleResult mysqlpp::Query::execute();為例,讓我們來看一下MYSQL++是如何設置這個SimpleResult。
再來看一下Query::insert_id( ), Query::affected_rows( ), Query::info(
),這幾個方法都直接delegate DBDriver的相關函數,直接返回了結果而已。
2) ResultBase
這個類型是StoreQueryResult和UseQueryResult的父類型,該類型其實沒有特別的含義,只是作為一個common
methods的container而已。但是該類型提供的幾乎所有的public methods都是和fields有關的,包括了
根據index查找field;
根據name查找field;
根據index查找到field的名字和屬性類型;
獲取當前所在的field(ResultBase內部會有一個mutable的index名為current_field_用于指明當前fetch_field的是哪一個field,在fetch_field中該index會自增)
該類型的核心成員有如下幾個
Fields(std::vector) 類型的 fields_
FieldNames (繼承自std::vector<: string>)類型的 names_
FieldTypes ( 繼承自std::vector)類型的types_
其中FieldNames和FieldTypes都是被RefCountedPointer包裹著,估計這樣做能夠節省空間。關于Field類型在后續進行介紹。至于剛才說的幾個找field的操作,看著這幾個核心成員的類型還是比較好理解的。不就是在vector中不找。
需要額外關注的是以下這個最主要的構造函數
以下幾點需要注意,
names_和types_在new出來之后是不需要顯式delete的,因為他們都在智能指針RefCountedPointer包裹著。
成員初始化列表中的 fields_(Fields:: size_type(…)) 這一句其實調用的是
explicit std::vector::vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());
從以上構造函數可以看到,其實關于Field的信息還是從DBDriver中拿到的,然后關于FieldNames和FieldTypes的信息,則是通過這兩個類型自身的構造函數給實現的(其實就是收到ResultBase*,然后遍歷其中的成員變量
fields_ 再各求所需罷了。
為什么要有重新將指示field_當前index的指針重置的過程(dbd->field_seek(res,
0))?這是因為方便這個DBDriver再次循環訪問這些fields。
3) StoreQueryResult
該類型是同時集成了ResultBase和vecor類型(請注意了,這個Result居然是一個vecor!)文檔中說,該類型hold
results from a SQL query that returns rows: a specialization of std::vector
holding Row objects in memory so you get random-access semantics.
說白了,該類型在繼承了ResultBase之后,只有以下這個構造函數是比較要緊的了。
有以下幾點需要說明
StoreQueryResult繼承自std::vector
在成員初始化列表中,首先調用ResultBase的構造函數
list_type是std::vector的typedef,所以在list_type(…)這一行,直接根據DBDriver返回的結果的rows的數量就布置好了vector的長度。
MYSQL_ROW是MYSQL自帶的結構類型(定義域mysql.h中,typedef char **MYSQL_ROW;)
dbd->fetch_row(MYSQL_RES*)應該只是包裝了mysql_fetch_row(MYSQL_RES*)這個MySql C
API,而dbd->fetch_lengths(MYSQL_RES*)其實包裝的是mysql_fetch_lengths(MYSQL_RES*)這個MYSQL
C API,他獲取的是整個row的對應的所有field的長度。
這一次Query的結果在全部拷貝完之后就釋放了(dbd->free_result(res);)
如此一來,所有我們需要的信息都通過構造一個mysqlpp::Row對象來實現了。關于mysqlpp::Row的具體說明請看下文。
4) UseQueryResult
該類型拓展于ResultBase類型。根據MYSQL++ user
document的說法,UseQueryResule適用于For these large result sets,a “use” query tells the
database server to send the results back one row at a time, to be processed
linearly.
該類型的方法比StoreQueryResult豐富多了,主要體現在:
可以順序讀取行(mysqlpp::Row fetch_row() const;或者MYSQL_ROW fetch_raw_row()
const;)
可以獲取當前行的各個field的信息(const Field& fetch_field() const; const Field&
fetch_field(Fields::size_type i) const)
可以獲取當前行的所有fields的長度(const unsigned long* fetch_lengths() const;)
值得注意的是,UseQueryResult有一個成員變量mutable RefCountedPointer result_;
需要強調的有兩點
MYSQL_RES是 MYSQL C API
中的用于做為資源的結構體,獲取一行的函數mysql_fetch_one_row的參數就是MYSQL_RES*
RefCountedPointer是一個智能指針,但是就在定義這些result類型的result.h中,作者將其針對MYSQL_RES進行了具化,即
很顯然,這個是為了在ref
count為0時自動調用析構器而準備的,該Destroyer使用mysql_free_result來銷毀這里的result_,從而代替默認的delete操作。
接下來,我們來具體看幾個函數的實現。
構造函數
獲取fields的信息
請注意,這個result_是一個RefCountedPointer,所以調用的raw方法將會返回MYSQL_RES*
獲取一行數據
核心的做法就是利用MYSQL_ROW? DBDriver::fetch_row(MYSQL_RES* res)
const。其實質也就是調用了mysql_fetch_one_row( )這個C API。然后直接生成一個mysqlpp::Row對象,返回。
原文:http://www.cnblogs.com/aicro/p/3633506.html
總結
以上是生活随笔為你收集整理的mysql 获取结果_【原创】7. MYSQL++中的查询结果获取(各种Result类型)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是内连接查询?
- 下一篇: excel数据库_从案例说excel如何