一个很酷的Modern C++ ORM库----ormpp

english wike 感谢Selina同学将中文wiki翻译为英文。

目录

ormpp的目标

ormpp最重要的目标就是让c++中的数据库编程变得简单,为用户提供统一的接口,支持多种数据库,降低用户使用数据库的难度。

ormpp的特点

ormpp是modern c++(c++11/14/17)开发的ORM库,目前支持了三种数据库:mysql, postgresql和sqlite,ormpp主要有以下几个特点:

header only

cross platform

unified interface

easy to use

easy to change database

你通过ormpp可以很容易地实现数据库的各种操作了,大部情况下甚至都不需要写sql语句。ormpp是基于编译期反射的,会帮你实现自动化的实体映射,你再也不用写对象到数据表相互赋值的繁琐易出错的代码了,更酷的是你可以很方便地切换数据库,如果需要从mysql切换到postgresql或sqlite只需要修改一下数据库类型就可以了,无需修改其他代码。

快速示例

这个例子展示如何使用ormpp实现数据库的增删改查之类的操作,无需写sql语句。

#include "dbng.hpp"

using namespace ormpp;

struct person

{

int id;

std::string name;

int age;

};

REFLECTION(person, id, name, age)

int main()

{

person p = {1, "test1", 2};

person p1 = {2, "test2", 3};

person p2 = {3, "test3", 4};

std::vector v{p1, p2};

dbng mysql;

mysql.connect("127.0.0.1", "dbuser", "yourpwd", "testdb");

mysql.create_datatable();

mysql.insert(p);

mysql.insert(v);

mysql.update(p);

mysql.update(v);

auto result = mysql.query(); //vector

for(auto& person : result){

std::cout<

}

mysql.delete_records();

//transaction

mysql.begin();

for (int i = 0; i < 10; ++i) {

person s = {i, "tom", 19};

if(!mysql.insert(s)){

mysql.rollback();

return -1;

}

}

mysql.commit();

}

如何编译

编译器支持

需要支持C++17的编译器, 要求的编译器版本:linux gcc7.2, clang4.0; windows >vs2017 update5

数据库的安装

因为ormpp支持mysql, postgresql和sqlite,所以需要安装mysql,postgresql,postgresql官方提供的libpq以及sqlite3,安装之后,在CMakeLists.txt配置目录和库路径。

依赖的第三方库

序列化部分用的是iguana,所以需要下载iguana的代码,直接在ormpp目录下git clone https://github.com/qicosmos/iguana.git

上面三步完成之后就可以直接编译了。

接口介绍

ormpp屏蔽了不同数据库操作接口的差异,提供了统一简单的数据库操作接口,具体提供了数据库连接、断开连接、创建数据表、插入数据、更新数据、删除数据、查询数据和事务相关的接口。

接口概览

//连接数据库

template

bool connect(Args&&... args);

//断开数据库连接

bool disconnect();

//创建数据表

template

bool create_datatable(Args&&... args);

//插入单条数据

template

int insert(const T& t, Args&&... args);

//插入多条数据

template

int insert(const std::vector& t, Args&&... args);

//更新单条数据

template

int update(const T& t, Args&&... args);

//更新多条数据

template

int update(const std::vector& t, Args&&... args);

//删除数据

template

bool delete_records(Args&&... where_conditon);

//查询数据,包括单表查询和多表查询

template

auto query(Args&&... args);

//执行原生的sql语句

int execute(const std::string& sql);

//开始事务

bool begin();

//提交事务

bool commit();

//回滚

bool rollback();

具体的接口使用介绍

先在entity.hpp中定义业务实体(和数据库的表对应),接着定义数据库对象:

#include "dbng.hpp"

using namespace ormpp;

struct person

{

int id;

std::string name;

int age;

};

REFLECTION(person, id, name, age)

int main(){

dbng mysql;

dbng sqlite;

dbng postgres;

//......

}

连接数据库

template bool connect(Args&&... args);

connect exmple:

mysql.connect("127.0.0.1", "root", "12345", "testdb")

postgres.connect("127.0.0.1", "root", "12345", "testdb")

sqlite.connect("127.0.0.1", "root", "12345", "testdb")

返回值:bool,成功返回true,失败返回false.

断开数据库连接

bool disconnect();

disconnect exmple:

mysql.disconnect();

postgres.disconnect();

sqlite.disconnect();

注意:用户可以不用显式调用,在数据库对象析构时会自动调用disconnect接口。

返回值:bool,成功返回true,失败返回false.

3.创建数据表

template

bool create_datatable(Args&&... args);

create_datatable example:

//创建不含主键的表

mysql.create_datatable();

postgres.create_datatable();

sqlite.create_datatable();

//创建含主键和not null属性的表

ormpp_key key1{"id"};

ormpp_not_null not_null{{"id", "age"}};

person p = {1, "test1", 2};

person p1 = {2, "test2", 3};

person p2 = {3, "test3", 4};

mysql.create_datatable(key1, not_null);

postgres.create_datatable(key1, not_null);

sqlite.create_datatable(key1);

注意:目前只支持了key和not null属性,并且只支持单键,还不支持组合键,将在下一个版本中支持组合键。

返回值:bool,成功返回true,失败返回false.

4.插入单条数据

template

int insert(const T& t, Args&&... args);

insert example:

person p = {1, "test1", 2};

TEST_CHECK(mysql.insert(p)==1);

TEST_CHECK(postgres.insert(p)==1);

TEST_CHECK(sqlite.insert(p)==1);

返回值:int,成功返回插入数据的条数1,失败返回INT_MIN.

5.插入多条数据

template

int insert(const std::vector& t, Args&&... args);

multiple insert example:

person p = {1, "test1", 2};

person p1 = {2, "test2", 3};

person p2 = {3, "test3", 4};

std::vector v1{p, p1, p2};

TEST_CHECK(mysql.insert(v1)==3);

TEST_CHECK(postgres.insert(v1)==3);

TEST_CHECK(sqlite.insert(v1)==3);

返回值:int,成功返回插入数据的条数N,失败返回INT_MIN.

更新单条数据

template int update(const T& t, Args&&... args);

update example:

person p = {1, "test1", 2};

TEST_CHECK(mysql.update(p)==1);

TEST_CHECK(postgres.update(p)==1);

TEST_CHECK(sqlite.update(p)==1);

注意:更新会根据表的key字段去更新,如果表没有key字段的时候,需要指定一个更新依据字段名,比如

TEST_CHECK(mysql.update(p, "age")==1);

TEST_CHECK(postgres.update(p, "age")==1);

TEST_CHECK(sqlite.update(p, "age")==1);

返回值:int,成功返回更新数据的条数1,失败返回INT_MIN.

5.插入多条数据

template

int update(const std::vector& t, Args&&... args);

multiple insert example:

person p = {1, "test1", 2};

person p1 = {2, "test2", 3};

person p2 = {3, "test3", 4};

std::vector v1{p, p1, p2};

TEST_CHECK(mysql.insert(v1)==3);

TEST_CHECK(postgres.insert(v1)==3);

TEST_CHECK(sqlite.insert(v1)==3);

注意:更新会根据表的key字段去更新,如果表没有key字段的时候,需要指定一个更新依据字段名,用法同上。

返回值:int,成功返回更新数据的条数N,失败返回INT_MIN.

删除数据

template bool delete_records(Args&&... where_conditon);

delete_records example:

//删除所有数据

TEST_REQUIRE(mysql.delete_records());

TEST_REQUIRE(postgres.delete_records());

TEST_REQUIRE(sqlite.delete_records());

//根据条件删除数据

TEST_REQUIRE(mysql.delete_records("id=1"));

TEST_REQUIRE(postgres.delete_records("id=1"));

TEST_REQUIRE(sqlite.delete_records("id=1"));

返回值:bool,成功返回true,失败返回false.

7.单表查询

template

auto query(Args&&... args);

//如果T是一个反射对象则返回的是单表查询结果vector

template

std::vector query(Args&&... args);

single table query example:

auto result = mysql.query();

TEST_CHECK(result.size()==3);

auto result1 = postgres.query();

TEST_CHECK(result1.size()==3);

auto result2 = sqlite.query();

TEST_CHECK(result2.size()==3);

//可以根据条件查询

auto result3 = mysql.query("where id=1");

TEST_CHECK(result3.size()==1);

auto result4 = postgres.query("where id=2");

TEST_CHECK(result4.size()==1);

auto result5 = sqlite.query("where id=3");

返回值:std::vector,成功vector不为空,失败则为空.

8.多表或特定列查询

template

auto query(Args&&... args);

//如果T是一个tuple类型则返回的是多表或特定列查询,结果vector>

template

std::vector<:tuple>> query(Args&&... args);

multiple or some fields query example:

auto result = mysql.query<:tuple std::string int>>("select code, name, dm from person");

TEST_CHECK(result.size()==3);

auto result1 = postgres.query<:tuple std::string int>>("select code, name, dm from person");

TEST_CHECK(result1.size()==3);

auto result2 = sqlite.query<:tuple std::string int>>("select code, name, dm from person");

TEST_CHECK(result2.size()==3);

auto result3 = mysql.query<:tuple>>("select count(1) from person");

TEST_CHECK(result3.size()==1);

TEST_CHECK(std::get<0>(result3[0])==3);

auto result4 = postgres.query<:tuple>>("select count(1) from person");

TEST_CHECK(result4.size()==1);

TEST_CHECK(std::get<0>(result4[0])==3);

auto result5 = sqlite.query<:tuple>>("select count(1) from person");

TEST_CHECK(result5.size()==1);

TEST_CHECK(std::get<0>(result5[0])==3);

返回值:std::vector<:tuple>,成功vector不为空,失败则为空.

9.执行原生sql语句

int execute(const std::string& sql);

execute example:

r = mysql.execute("drop table if exists person");

TEST_REQUIRE(r);

r = postgres("drop table if exists person");

TEST_REQUIRE(r);

r = sqlite.execute("drop table if exists person");

TEST_REQUIRE(r);

注意:execute接口支持的原生sql语句是不带占位符的,是一条完整的sql语句。

返回值:int,成功返回更新数据的条数1,失败返回INT_MIN.

10.事务接口

开始事务,提交事务,回滚

//transaction

mysql.begin();

for (int i = 0; i < 10; ++i) {

person s = {i, "tom", 19};

if(!mysql.insert(s)){

mysql.rollback();

return -1;

}

}

mysql.commit();

返回值:bool,成功返回true,失败返回false.

11.面向切面编程AOP

定义切面:

struct log{

//args...是业务逻辑函数的入参

template

bool before(Args... args){

std::cout<

return true;

}

//T的类型是业务逻辑返回值,后面的参数则是业务逻辑函数的入参

template

bool after(T t, Args... args){

std::cout<

return true;

}

};

struct validate{

//args...是业务逻辑函数的入参

template

bool before(Args... args){

std::cout<

return true;

}

//T的类型是业务逻辑返回值,后面的参数则是业务逻辑函数的入参

template

bool after(T t, Args... args){

std::cout<

return true;

}

};

注意:切面的定义中,允许你只定义before或after,或者二者都定义。

//增加日志和校验的切面

dbng mysql;

auto r = mysql.warper_connect("127.0.0.1", "root", "12345", "testdb");

TEST_REQUIRE(r);

roadmap

支持组合键。

多表查询时增加一些诸如where, group, oder by, join, limit等常用的谓词,避免直接写sql语句。

增加日志

增加获取错误消息的接口

支持更多的数据库

增加数据库链接池

联系方式

mpp新增一个字段_ormpp--一个很酷的Modern C++ ORM库相关推荐

  1. mpp新增一个字段_如何快速新增百万测试数据?

    柠檬班的APP上线之前,需要一百万个学员的信息进行压力测试. 那么数据从哪里来呢?直接找开发帮忙?可能会被他鄙视! 一条一条去insert?嗯,算了下大概需要20年! 不用怕,Happy老师接下来教你 ...

  2. 在数据库中如何新增一个字段?

    工作中常会用到:交给测试时,会让交付新增的字段的SQL语句. 如何在数据库中新增一个字段: alter TABLE t_Execution(表名) add FIsModifyQuote(列名) int ...

  3. mysql表中指定位置新增一个字段

    在表test种,新增一个字段:status,并且status字段放在id后面 alter table + 表名 + add + 要添加的字段 字段类型 + (comment +注释+) after + ...

  4. mysql表 新增一个字段

    mysql表中在指定位置新增一个字段 原表结构,表名number 目的: 在字段numid 后新增一个name字段 alter table number add name varchar(100) c ...

  5. magento 为用户注册增加一个字段(转)

    步骤 I. 加一个occupation/title字段到用户注册页,差不多在register.html的54行,在email下方加一个Occupation显示代码 代码: <li> < ...

  6. sql语句查询商品的一二三级分类都是一个字段怎么办_畅购商城(三):商品管理...

    好好学习,天天向上 本文已收录至我的Github仓库「DayDayUP」:github.com/RobodLee/DayDayUP,欢迎Star 小练手 这里有三个小练手的任务,内容比较简单,就是对一 ...

  7. mongodb如何实现更新一个字段的值为另外一个字段的值?

    转载自   mongodb如何实现更新一个字段的值为另外一个字段的值? db.CargoUserProfiles.find().forEach(function(item){db.CargoUserP ...

  8. sql 只要一个字段相同则只显示一条数据_数据库

    数据库:管理数据的仓库,其本质是一种数据结构. 一.数据 数据:即信息,包括视觉信息.听觉信息等等.当前数据库主要存储的是视觉信息(数字.文字等等) 二.数据库的组成 数据库是由一张张数据表组成的. ...

  9. mysql查询结果某个字段设置为固定值_MySQL使用select查询时,在查询结果中增加一个字段并指定固定值...

    假设需求是这样的: mysql> desc user; +-------+----------+------+-----+---------+----------------+ | Field ...

  10. mysql 删除一个字段语句怎么写_删除的sql语句怎么写

    1. 删除一个表的sql 语句怎么写啊 使用drop语句,drop table (需要删除表的名字). drop是删除整个表,delete是删除表的内容. drop语句的作用:删除内容和定义,释放空间 ...

最新文章

  1. Mysql加锁过程详解(3)-关于mysql 幻读理解
  2. Liux技巧总结之--解压各种文件
  3. Spring Cloud Alibaba - 20 Nacos StandAlone模式下的数据存储(Derby)及新增登录用户
  4. 力扣刷题流程-参考别人的经验觉得很有道理的
  5. 腾讯或联姻优酷,微信嫁女模式引发互联网通婚潮流
  6. 7-Mybatis 连接池与事务深入
  7. 汪文君PowerMock实战视频
  8. 用scratch编写游戏-数字华容道(不移动块法)
  9. 二叉树期权定价与BSM期权定价
  10. 什么是TypeScript?本文介绍TypeScript基本用法和语法。
  11. Matlab图像处理笔记--图像修复
  12. java lda主题模型_主题模型(一):LDA 基本原理
  13. 计算机联盟社团团活动总结,社团活动总结
  14. 转载——神经网络中mAP相关概念
  15. 难道我的博客也成了名人博客?
  16. Esxi虚拟机安装黑群晖实践
  17. 网页中在线玩圆桌骑士
  18. 技术点:weekMap和Map的区别
  19. linux debian_Debian Linux | 第1部分
  20. HTCviveVR基于unity开发搭建初始界面

热门文章

  1. 计算机应用行业平均市盈率,申万行业指数:二级行业:市盈率:医疗器械
  2. Mini CFA 考试练习题 Ethics and Investment Professionalism
  3. 神奇的三门问题,到底换不换门
  4. grok java_ELK实战 - Grok简易入门
  5. 【杂七杂八】《我叫MT online》反编译解析
  6. Android接入腾讯Bugly统计SDK
  7. 考研数学公式默写记忆PDF
  8. 苹果iphone手机蓝牙自动打开故障怎么解决
  9. javaweb验证码明明输入正确却还是提示错误,验证码session不同步、不一致问题
  10. Outlook 与企业微信邮箱通讯录同步