一、mysqlpp::Row類型
在之前的介紹中我們看到了如何通過mysqlpp::Query找到各種Result類型,然后又仔細分析了各種Result類型又是如何生成對應的Row類型(如下所示)。
接下去的問題就是,到底mysqlpp::Row是什么。
1. Row類型的使用(先不提SSQLS)
還是先來看如何使用這個Row類型,照樣是通過sample程序。
mysqlpp::Connection conn(false); conn.connect(...); mysqlpp::Query query = conn.query("select * from stock"); mysqlpp::UseQueryResult res = query.use(); while (mysqlpp::Row row = res.fetch_row()) { cout << setw(30) << row["item"] << ' ' << setw(9) << row["num"] << endl; }
OR
mysqlpp::Connection conn(false); conn.connect(...); mysqlpp::Query query = conn.query("select * from stock"); mysqlpp::UseQueryResult res = query.use(); while (mysqlpp::Row row = res.fetch_row()) { cout << setw(30) << row[0] << ' ' << setw(9) << row[1] << endl; }
上面的例子中提到的兩種最為基本的用法,主要就是查看每行數據的各個列的不同方式。至於查找Row的列的信息,可以通過row[0]等返回回來的String,具體可以看下文和對於mysqlpp::String的介紹的章節。
2. mysqlpp::Row的實現
關於mysqlpp::Row的定義主要在row.h和row.cpp中。在說明中,我們可以看到,作者對Row的定義是const,這是因為他認為通過返回的Row去修改database是不合適的。所以不直接從vector進行派生,而自己去實現一些必要的方法。
mysqlpp::Row是直接從OptionalExceptions進行派生的。
- 成員變量
list_type data_;
RefCountedPointer<FieldNames> field_names_;
bool initialized_;
list_type是什么?typedef std::vector<mysqlpp::String> list_type;
FieldNames是一個派生自vecot<std::string>的類型
在類型聲明的一開頭,作者首先typedef了list_type相關的迭代器,反響迭代器,引用迭代器,元素類型值,元素類型長度等信息。
- 成員方法
首先來看各種構造方法和等號賦值方法。
主要定義了兩種構造器
主要看一下在本節一開始的實例中所使用的第二個構造器。
首先我們看到的是使用一個initialized_進行構造成功與否的保護,估計在之后所有的方法上都會先對這個變量進行查詢,如果是false直接返回錯誤或者拋出異常。
其次,是對於data_(一個vector<String>類型)的初始化和填充,需要注意的是第45行。value_type是這樣定義的,也就是一個vector<String>::value_type
查看STL文檔得知,vector<T>::value_type是A type that represents the data type stored in a vector. value_type is a synonym for the template parameter Type.換句話說,作者為了減少冗余,這里采用了通用的方式。值得學習!
所以說,其實在第45行,主要做的事情就是調用mysqlpp:: String的構造函數,這個請查看String的介紹。
這里還要注意的是第48行,跟着進去看到的是ResultBase:: field_type( )方法,定義是
又出現了熟悉的value_type,那么FieldTypes是什么呢?
又回到了之前介紹過的mysql_type_info。這樣子即使你沒有看過String的構造函數,你也已經很明白了,這個String很神通廣大,他居然能夠知道值以及具體的類型!也就是說,MySQL++就用了一個String包裝了MYSQL C API中的行信息和行所對應的列的信息。
接下來在52行把所有的field_names的信息傳遞給了mysqlpp::Row的成員變量field_names_,所有都已經成功了之后,就大膽地設置初始化標志為true。
再來分析一下在mysqlpp::Row中delegate std::vector的方法
不多說,完全就是delegate,只不過原來一直沒有注意過一點的是,vector<T>:: begin( )居然被定義了兩個版本(只怪自己學藝不精)
iterator begin(); const_iterator begin() const;
當然,上面用的版本都是非const版本,這是因為data_被定義為vector<String>沒有帶const,但是返回值都是const的!
順帶便說一下,const_reference以及const_iterator的定義
還有就是
獲取Row中Field值的方法
從上面的例子中我們可以簡單的看到,要獲取一行數據的值還是很簡單的,主要的方法就是通過operator [ ]
方法一,通過index查找Row中對應的field的值
再來說明一下上面提到的為什么該參數一定要是int而不是size_type的問題。下文我們可以知道,作者重載了一個operator[](char*)。如果出現了row[0]或者row[NULL](假設這個平台將NULL定義為0),我們有理由說編譯器會搞不清楚到底你要的是size_type還是char*,畢竟我們同樣可以把NULL賦值給char*。但是如果有了int,由於0是int型,所以會被匹配到這里。
這里的at方法還是很簡單的。
方法二,通過field的字符串形式的name來查找Row中對應的field的值
其中field_num方法的定義如下
該函數的實現代碼如下,
需要注意的是划紅色圈的地方,這里其實調用的是mysqlpp:: FieldNames(一個派生自vector<string>的類型)的operator[ ]的重載方法
以下這些方法是用於SSQLS,基於value_list_b結構體
equal_list
在Row的定義中,我們可以看到兩個同名不同參的函數equal_list,這兩個函數主要用在了SSQLS中,用於生成"equals clause",例如在SELECT語句中的WHERE就是一個典型的"equals clause",例如,
SELECT * FROM Tbl1 WHERE id = ‘1’, name = ‘root’
這個是需要配合使用equal_list_b結構以及一個用於做quoting和escaping的類型。
這幾個重要方法請參看SSQLS的具體解釋。
field_list
這幾個方法同樣也是用於SSQLS的,主要用於返回各種FieldNames。這個函數會有一些輸入(某些重構是vector<bool>,有些就是很多bool參數)來表明一個row中哪些field是需要被返回到結果集中的。不需要的就用false。
value_list
這個函數是獲取mysqlpp::Row的整個(或者部分)值的函數。這個函數會有一些輸入(某些重構是vector<bool>,有些就是很多bool參數)來表明一個row中哪些field是需要被返回到結果集中的。不需要的就用false。
原創作品,轉載請注明出處www.cnblogs.com/aicro。



















