欢迎技术交流和帮助,提供IT相关服务,如果有需要,请联系博主QQ: 503587937
项目里面目前还是是用手写的SQL语句,很麻烦,也很容易出问题,很早以前就想过使用C++的ORM框架,当时一直没找到合适的,一直就搁置着。如果没找到合适的框架,就会自己手撸一个了。
今天突然发现了一个挺好用的C++ ORM框架,SQLPP11,比我当时的想法还好,比如查询语句,当时我的想法是
select(tablename).where("i < 7").and("j > 8").or("x < 2")
SQLPP11的则是:
select(foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17 and foo.name.like("%bar%"))
比起单纯地使用字符串,该方法可以有更好的安全性和更简单的代码提示
源码的地址在 https://github.com/rbock/sqlpp11,可以自行编译,也可以用VCPKG下载,推介使用VCPKG
在windows下源码建议使用vcpkg下载
vcpkg install sqlpp11:x64-windows
vcpkg install sqlpp11-connector-sqlite3:x64-windows
示例教程均使用sqlite3数据库, VS2015编译
需要安装python
创建一个表,并且将该SQL语句保存为student.sql
```
CREATE TABLE "Student" (
"name" TEXT,
"age" INTEGER
);
```
在vcpkg的 installed\x64-windows\scripts 目录下,有一个sqlpp11-ddl2cpp的脚本,该脚本负责把SQL的语句转换成cpp的结构,运行如下:
python sqlpp11-ddl2cpp Student.sql ./Student TestProject
在当前目录下就会产生一个Student.h的文件,打开后可以看到,就是该数据库的C++的结构了
SQLITE类型 | C++里面的类型 |
---|---|
DateTime(time_point) | std::chrono::system_clock |
Text | std::string |
Integer | int64 |
no value | void |
bool | bool |
blob | std::vector < std::uint8_t > |
#include "sqlpp11/sqlpp11.h"
#include "sqlpp11/sqlite3/sqlite3.h"
#include "Student.h"
#include <sstream>
#include <stdlib.h>
namespace sql = sqlpp::sqlite3;
int main(void)
{
sql::connection_config config;
config.path_to_database = ":memory:";
config.flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
config.debug = false;
try
{
sql::connection db(config);
TestProject::Student stu{};
db.execute(R"(CREATE TABLE "Student" ("name" TEXT,"age" INTEGER))");
// 单独插入一行
db(insert_into(stu).set(stu.age = 12, stu.name = "one"));
// 插入多行
auto multi_insert = insert_into(stu).columns(stu.age, stu.name);
for (int i = 0; i < 10; i++)
{
std::ostringstream ostr;
ostr << "linyiong" << i;
multi_insert.values.add(stu.age = i, stu.name = ostr.str());
}
db(multi_insert);
// 删除
db(remove_from(stu).where(stu.age==12));
// 查询
for (const auto& row : db(select(stu.name, stu.age)
.from(stu)
.where(stu.age > 1)))
{
std::cout << row.name << ":" << row.age << std::endl;
}
// 更新
db(update(stu).set(stu.name = "linyilong3").where(stu.age>3));
for (const auto& row : db(select(stu.name, stu.age)
.from(stu)
.where(stu.age > 1)))
{
std::cout << row.name << ":" << row.age << std::endl;
}
}
catch (std::exception& except)
{
std::cout << except.what() << std::endl;
}
system("pause");
}