文章目录
后面可能用其他的ORM,因为litesql有可以生成配置相关的XML,所以后面就选择litesql,不用odb++
1.odb组成部分
①odb编译器:生成应用程序需要的持久化对象的代码。odb编译器是一个真正的c++编译器除了它产生的是c++代码而不是机器码。
②odb运行库libodb
③特定的数据库相关的链接库
2.使用步骤
1)声明持久化的类
#include <string>
#include <odb/core.hxx>
using namespace std;
#pagma db object // 表明接下来的类是一个数据库相关的类
#pragma db id //表明接下来这个字段是这个持久化类的标识符字段
//一般而言,这两条语句是声明一个持久化类所必需的两条语句。但是我们也可以不用#pragma db id,而是使用#pragma db object no_id,表明这个持久化类没有标识符,如上例子
#pragma db object no_id //
class person
{
public:
friend class odb::access;//在我们将类的构造函数或者将数据成员声明为私有时,odb的access类可以访问我们的数据成员和构造函数。
public:
unsigned long id;
string name;
string sex;
unsigned short age;
};
- 备注
①我们也可以不声明类的构造函数,此时我们声明一个对象时只能以查询的数据库实例来初始化这个对象。
②odb官方文档只提供了类的构造函数的声明,没有提供实现,所有如果完全按照官方文档hello world的例子是会出错的
③如果数据成员不能正常访问时,odb编译器会自动寻找合适的访问器和修改函数。例如如果存在name_数据成员,那么odb编译器会试着寻找get_name(), getName(), getname(),name()获去name_的值,寻找set_name(),setName(),setname(),name()设置name_的值。odb编译器也会提供通用的set()和get()函数在找不到访问器和修改函数的情况下使用。例子如下
#pragma db object
class person
{
public:
const std::string& get_name () const;
std::string& set_name ();
private:
std::string name_; // Uses get_name()/set_name() for access.
};
2)生成数据库支持的代码(用安装的ODB Compiler编译Person.h得到新的)
- ①odb -d mysql --generate-query --generate-schema person.hxx,直接运行这条语句会生成会生成四个文件,如下person-odb.cxx,person-odb.hxx,person-odb.ixx ,person.sql。
- ②person.sql是自动生成的建立表的sql语句。
- ③其他三个是操作数据库支持的代码。
- ④上述命令 --generate-query选项是生成数据查询支持的代码,–generate-schema选项是生成创建数据表相关的代码
3)数据库增删改查的C++代码
/*************************************************************************
> File Name: test.cpp
> Author: aben
> Mail: aben@taomee.com
> Created Time: Mon 02 Apr 2018 07:33:28 AM PDT
************************************************************************/
#include <iostream>
#include <odb/database.hxx>
#include <odb/transaction.hxx>
#include <odb/mysql/database.hxx>
#include "person-odb.hxx"
using namespace std;
using namespace odb::core;
int main (int argc, char* argv[])
{
person aben, wenhao;
aben.id = 1;aben.name = "aben";aben.sex = "man";aben.age = 23;
wenhao.id = 2;wenhao.name = "wenhao";wenhao.sex = "man";wenhao.age = 22;
typedef odb::query<person> query;
typedef odb::result<person> result;
try
{
shared_ptr<odb::mysql::database> db;
db.reset(new odb::mysql::database ("root", "123456", "test"))
transaction t (db->begin ());
t.tracer (stderr_tracer);
db->persist (aben);
db->persist (wenhao);
query q(query::id == 2);
result r = db->query<person>(q);
for (auto i:r)
{
cout << "{id:" << i.id << " name:" << i.name << " sex:" << i.sex << " age:" << i.age << "}" << endl;
}
t.commit ();
}
catch (const odb::exception& e)
{
cerr << e.what () << endl;
}
return 0;
}
4)编译运行指令
g++ -std=c++11 -o driver test.cpp person-odb.cxx -lodb-mysql -lodb
./driver
3.其他问题
1)odb查询过程迭代器失效的问题
- odb查询文档代码
odb查询在odb的官方文档中介绍很详细。我们简单介绍如下。
typedef odb::query<person> query;
typedef odb::result<person> result;
query q(query::first == "John");
result r = db->query(q);
- 问题产生原因
当我们查询到结果之后,常见的操作如下。此时切记,在进行操作时切勿提交事务或者回滚事务否则会发生迭代器失效。
- 代码示例
for (auto i : r)
{
//某种操作;
}