背景
最近一直在看odb官网上odb-manual,由于是全英文文档,仔细看过一遍之后虽然感觉基本了解,但是隔几天之后再翻开时又要逐一回忆当初理解的一些细节,毕竟不是母语,没有那种一看就条件反射式的想起来,所以把一些key word记录下来,避免下次重复花时间来消化知识。对于一个coder,能够用代码来阐述的,就尽量不用文字,所以在记录过程中尽量通过代码来展示一些api的用法。
使用说明
本文基于odb官方手册为指导,通过自己的理解之后用尽可能通俗易懂的文字来阐述相关用法。站在应用编程的角度,将文档中常用知识点、易错点进行翻译整理。同时本文也弱化掉了一些不常用的知识点,基于这种考虑主要是由于本文的立足点是为了使编程人员尽快上手开发,如果将一些不常用的知识点也罗列其中会显得繁杂且冗余,所以如果在开发过程中遇到本文未提及的点可以回到odb官方手册进行查询。
持久化对象的处理
-
Objects and Values: Objects属于具有全局唯一标识的实体entity的对象,相当于数据库中的某一条记录,具有id标识符。而Values被称为值对象,这些对象不会单独存在于数据库中,而是存在于实体entity对象的某一个成员变量中。
-
事务(Transaction): 事务是原子(Atomic),一致(consistent),隔离(isolated)和持久(durable)(ACID)的工作单元。事务的代码结构如下:
#include <odb/transaction.hxx> transaction t (db.begin ()) // Perform database operations. t.commit ();
odb::transaction 类有如下接口:
namespace odb { class transaction { public: typedef odb::database database_type; typedef odb::connection connection_type; explicit transaction (transaction_impl*, bool make_current = true); transaction (); void reset (transaction_impl*, bool make_current = true); void commit (); void rollback (); database_type& database (); connection_type& connection (); bool finilized () const; public: static bool has_current (); static transaction& current (); static void current (transaction&); static bool reset_current (); // Callback API. // public: ... }; }
解释说明:
- commit():事务提交
- rollback(): 事务回滚,当然如果没有显示支持需要commit或rollback的话,当transaction类析构时会自动回滚。
- database(): 返回当前事务的database
- connection(): 返回当前事务的connection
- current(): 返回线程的active态的transaction,如果没有active transaction的话,则会抛出odb::not_in_transaction的异常,如果我们想check一下是否有一个有效的transaction在这个线程中,我们可以使用has_current()接口来实现。
- transaction的构造函数输入参数make_current如果为false,则不会自动创建active transaction,之后在使用时通过current()接口人为创建。
- reset_current(): 清除当前的active transaction
以下是针对同一个线程多个transaction的实例代码
transaction t1 (db1.begin ()); // Active transaction. transaction t2 (db2.begin (), false); // Not active. // Perform database operations on db1. transaction::current (t2); // Deactivate t1, activate t2. // Perform database operations on db2. transaction::current (t1); // Switch back to t1. // Perform some more database operations on db1. t1.commit (); transaction::current (t2); // Switch to t2. // Perform some more database operations on db2. t2.commit ();
- reset(): 允许我们重新使用相同的transaction实例来实现多个数据库的事务操作。通常在我们commit()之后后需要发起事务的场景,示例代码如下:
transaction t (db.begin ()); for (size_t i (0); i < n; ++i) {