1.查询条件拼接是注意字符串头是否为空
# query字符串头不为空
std::string query = "select * from Users where id =1";
typedef odb::result<ODBORM::Users> result;
result rs(db->query<ODBORM::Users>(query));
# 如果开了odb的 odb::core::transaction t(db->begin());
#t.tracer(odb::stderr_full_tracer);
# 在终端看到这个执行是一个正常的sql: select * from Users where id =1
# query字符串头为空
std::string query = " select * from Users where id =1";
#这个时候会在终端看到这个执行是一个在前面拼接了一个where 的sql: where select * from Users where id =1
2.根据需要创建不同表的schema,用于创建在不同的数据库中
/*odb 使用时要先编译相应的头文件xxx.h,生成xxx-odb.cxx,xxx-odb.ixx,xxx-odb.hxx
目前有个需求 a.h 描述的表生成在a.db, b.h描述的表生成在b.db
*/
# 首先编译时指定schema-name
/*cd $(ProjectDir)src\odbormtype\a\ && odb.exe --std c++11 --database sqlite --generate-query --generate-schema --schema-name a -I ../../../.. a.h
cd $(ProjectDir)src\odbormtype\b\ && odb.exe --std c++11 --database sqlite --generate-query --generate-schema --schema-name b -I ../../../.. b.h
*/
# 代码中
auto db = std::make_shared<odb::sqlite::database>("a.db",
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
odb::core::transaction t(db->begin());
odb::schema_catalog::create_schema(*db, "a");
t.commit();
auto db = std::make_shared<odb::sqlite::database>("b.db",
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
odb::core::transaction t(db->begin());
odb::schema_catalog::create_schema(*db, "b");
t.commit();
3.odb中声明了一个事务,只有这个事务commit的了才能启动另外的事务,即使不同的数据库事务也不可以交织在一起。但是可以声明同一个事务,跨数据库操作,在该事务中一起提交
/*In the above example the employee class will be stored in the 'main'
database (this is the name given by SQLite to the first opened database).
The employer class will be stored in the 'extra' database. Here is how
we can attach the 'extra' database:*/
odb::sqlite::database db ("main.db"); // main -> main.db
db.execute ("ATTACH DATABASE extra.db AS extra");
employee ee;
employer er;
transaction t (db.begin ());
db.persist (ee); // Goes to main.db.
db.persist (er); // Goes to extra.db.
t.commit ();
参考URL:[odb-users] Handling Multiple Databases/Threads in ODB
4.在connection中execute执行set pragam相关命令
db->connection()->execute("PRAGMA journal_mode=WAL");
5.出现timeout或者deadlock使用retry方案,如果频繁出现或者拆分库表
bool retryDbTransaction(std::function<void()> &func) {
int max_retries = 10;
for (unsigned short retry_count(0);; retry_count++) {
try {
// odb::core::transaction t(projectDb->begin());
func();
return true;
} catch (const odb::recoverable &e) {
if (retry_count > max_retries) {
return false;
} else {
continue;
}
} catch (const odb::timeout &e) {
if (retry_count > max_retries) {
return false;
} else {
continue;
}
}
}
}
6.查询也会使用事务,避免查询影响写,可以考虑使用wal机制
参考url:Write-Ahead Logging