ODB 入門介紹(一)
阿新 • • 發佈:2019-02-12
- 編寫person.hxx檔案
// file : self/person.hxx // copyright : not copyrighted - public domain #ifndef PERSON_HXX #define PERSON_HXX #include <string> #include <cstddef> #include <odb/core.hxx> // 包含odb::access #pragma db object // 告訴編譯器這是一個 persistent class class person { public: person(const std::string& first, const std::string& last, unsigned short age) : first_(first), last_(last), age_(age) { } const std::string& first() const { return first_; } const std::string& last() const { return last_; } unsigned short age() const { return age_; } void age(unsigned short age) { age_ = age; } private: friend class odb::access; // 讓預設的建構函式和其他類成員能夠訪問access類 person() {} // 這個建構函式在例項化一個persistent class時會用到 #pragma db id auto // 用來指定一個id, auto指明這個id的值是由資料庫自動分配的 unsigned long id_; std::string first_; std::string last_; unsigned short age_; }; #endif // PERSON_HXX
幾個主要的地方在程式碼中註釋了
-
用odb.exe生成對應的檔案 和sql檔案
執行 odb -d mysql --generate-query --generate-schema person.hxx
執行完畢後會生成幾個檔案
將這些檔案加到你的工程目錄中 -
main函式的編寫
// file : selfTest/driver.cxx // copyright : not copyrighted - public domain #include <memory> // std::auto_ptr #include <iostream> #include <odb/database.hxx> #include <odb/transaction.hxx> #include "database.hxx" //#include "person.hxx" #include "person-odb.hxx" using namespace std; using namespace odb::core; int main(int argc, char* argv[]) { try { //auto_ptr<database> db (create_database (argc, argv)); auto_ptr<odb::database> db( new odb::mysql::database("root", "123456", "odbtest", "localhost", 3306) ); unsigned long john_id, joe_id; // Create a few persistent person objects. // { person john("John", "Doe", 33); person jane("Jane", "Doe", 32); person joe("Joe", "Dirt", 30); transaction t(db->begin()); // Make objects persistent and save their ids for later use. // john_id = db->persist(john); db->persist(jane); joe_id = db->persist(joe); t.commit(); } } catch (const odb::exception& e) { cerr << e.what() << endl; return 1; } }
3.1 查詢
persist(value) 這個函式就相當於把value存在一個快取裡, 當執行完commit() 之後會執行sql語句 將這些資料儲存到資料庫中odb::query<> 查詢相關的類typedef odb::query<person> query; typedef odb::result<person> result; transaction t(db->begin()); result r(db->query<person>(query::age >= 30));
db->query<person>(query::age>=30) 意思是從資料中找 age>=30的所有行, 返回值是一個結果集 用 result r接住
使用的時候就像使用迭代器一樣使用這個結果集result::iterator it = r.begin(); for (; it != r.end(); ++it) { cout << "hello, " << it->first() << it->last() << " !" << endl; }
3.2 更新 update
看person.hxx中 有這個意思就是我們可以對這個欄位進行更新賦值{ transaction t(db->begin()); person* pPerson = db->load<person>(joe_id); pPerson->age(pPerson->age() + 1); db->update(*pPerson); t.commit(); }
db->load<person>(joe_id) 就是查詢joe_id的資料 返回的是一個person*的指標
然後呼叫 db->update(*pPerson)就可以這個玩家的資料, 執行t.commit()之後就可以更新到資料庫了
3.3 聚合查詢的結果
在檔案person.hxx中新增結構體#pragma db view object(person) struct person_stat { #pragma db column("count(" + person::id_ + ")") std::size_t count; #pragma db column("min(" + person::age_ + ")") unsigned short min_age; #pragma db column("max(" + person::age_ + ")") unsigned short max_age; };
重新生成odb -d mysql --generate-query --generate-schema person.hxx 檔案
然後在main檔案中新增程式碼transaction t(db->begin()); person_stat ps(db->query_value<person_stat>()); cout << endl << "count : " << ps.count << endl << "min age: " << ps.min_age << endl << "max age: " << ps.max_age << endl; t.commit();
這種方法是針對總是查詢返回一個元素的結果, 如果這樣寫就會方便很多, 一次把所有要查詢的單一元素聚合起來
3.4 刪除transaction t(db->begin()); db->erase<person>(john_id); t.commit();
通過key john_id 刪除對應的行