C++角度的gorm架构|青训营笔记

227 阅读2分钟

这是我参与[第五届青训营]的第六天

ORM(Object Relational Mapping)是在面向对象编程OOP和关系数据库之间的交互进行一个良好的基础构建。好的架构何以极大的简化流程,大部分情况下都可以提升效率和运行效果。

但是另一方面,如果SQL查询过于复杂可能效果没有想象的好。通常ORM会比使用SQL更慢。

在C++中,由于C++编译较慢,难以维护,网络框架较少,对应的ORM框架也不多。比较常见的有ODB、sqlbb11。

C++不支持反射,也就是说不能仅通过名称在运行时访问类/字段(也许可以从头写一个运行时?),这样的话进行ORM和序列化的过程就比较复杂,实现的结果也可能是难以优化的。

sqlbb11示例代码:

TabFoo foo;
Db db(/* some arguments*/);

// selecting zero or more results, iterating over the results
for (const auto& row : db(select(foo.name, foo.hasFun).from(foo).where(foo.id > 17 and foo.name.like("%bar%"))))
{
    if (row.name.is_null())
        std::cerr << "name is null, will convert to empty string" << std::endl;
    std::string name = row.name;   // string-like fields are implicitly convertible to string
    bool hasFun = row.hasFun;          // bool fields are implicitly convertible to bool
}

// selecting ALL columns of a table
for (const auto& row : db(select(all_of(foo)).from(foo).where(foo.hasFun or foo.name == "joker")))
{
    int64_t id = row.id; // numeric fields are implicitly convertible to numeric c++ types
}

// selecting zero or one row, showing off with an alias:
SQLPP_ALIAS_PROVIDER(cheese);
if (const auto& row = db(select(foo.name.as(cheese)).from(foo).where(foo.id == 17)))
{
    std::cerr << "found: " << row.cheese << std::endl;
}

// selecting a single row with a single result:
return db(select(count(foo.id)).from(foo).unconditionally()).front().count;

// A sample insert
db(insert_into(foo).set(foo.id = 17, foo.name = "bar", foo.hasFun = true));

// A sample update
db(update(foo).set(foo.hasFun = not foo.hasFun).where(foo.name != "nobody"));

// A sample delete
db(remove_from(foo).where(not foo.hasFun));

SQL和C++都是强类型的语言,在C++中提取对象成员字段名可以使用Hash Table来实现、ORM架构还需要考虑表达式系统,产生查询结果,推导查询结果,从字段生成表达式。

在C++中,转发和重载会遇到不小的问题。