官方参考文档
本文档内容是自己学习的一个记录,内容来自官方文档
https://www.oschina.net/p/odb-orm?hmsr=aladdin1e1
https://www.codesynthesis.com/products/odb/doc/manual.xhtml#1
ODB是什么?
ODB可以直接把C++的类对象映像成关系型数据库对象。
架构和工作流程
Hello World Example
头文件:
// file : hello/person.hxx
// copyright : not copyrighted - public domain
#ifndef PERSON_HXX
#define PERSON_HXX
#include <string>
#include <cstddef> // std::size_t
#include <odb/core.hxx>
// 定义class person为persistence class
#pragma db object
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:
// 定义友元函数,odb可以访问私有的默认构造函数
friend class odb::access;
// 定义默认构造函数用于odb编译器生成support code
person () {}
// 定义数据库的key值,并且这个key是database自生长的
#pragma db id auto
unsigned long id_;
std::string first_;
std::string last_;
unsigned short age_;
};
// 定义class person_stat 为 class person的view
// view
#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;
};
#endif // PERSON_HXX
应用文件:
// file : hello/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" // create_database
#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));
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 ();
}
typedef odb::query<person> query;
typedef odb::result<person> result;
// Say hello to those over 30.
//
{
transaction t (db->begin ());
result r (db->query<person> (query::age > 30));
for (result::iterator i (r.begin ()); i != r.end (); ++i)
{
cout << "Hello, " << i->first () << " " << i->last () << "!" << endl;
}
t.commit ();
}
// Joe Dirt just had a birthday, so update his age.
//
{
transaction t (db->begin ());
auto_ptr<person> joe (db->load<person> (joe_id));
joe->age (joe->age () + 1);
db->update (*joe);
t.commit ();
}
// Alternative implementation without using the id.
//
/*
{
transaction t (db->begin ());
// Here we know that there can be only one Joe Dirt in our
// database so we use the query_one() shortcut instead of
// manually iterating over the result returned by query().
//
auto_ptr<person> joe (
db->query_one<person> (query::first == "Joe" &&
query::last == "Dirt"));
if (joe.get () != 0)
{
joe->age (joe->age () + 1);
db->update (*joe);
}
t.commit ();
}
*/
// Print some statistics about all the people in our database.
//
{
transaction t (db->begin ());
// The result of this (aggregate) query always has exactly one element
// so use the query_value() shortcut.
//
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 ();
}
// John Doe is no longer in our database.
//
{
transaction t (db->begin ());
db->erase<person> (john_id);
t.commit ();
}
}
catch (const odb::exception& e)
{
cerr << e.what () << endl;
return 1;
}
}
编译,生成Database Support Code
odb -d mysql --generate-query person.hxx // 仅示例
生成:
person-odb.hxx, person-odb.ixx, person-odb.cxx
编译,生成database schema
odb -d mysql --generate-query --generate-schema person.hxx
这个命令除了生成上面的person-odb.hxx, person-odb.ixx, person-odb.cxx,还会生成
person.sql, which is the database schema for the persistent classes defined in person.hxx.
编译、链接生成应用程序。
- 编译
c++ -c driver.cxx
c++ -c person-odb.cxx
- 链接
c++ -o driver driver.o person-odb.o -lodb-mysql -lodb
- 创建database schema,使用前面生成的.sql文件
mysql --user=odb_test --database=odb_test < person.sql
- 运行程序
./driver --user odb_test --database odb_test