基于C++的ORM框架sqlpp11入门介绍(附MySQL运行实例)

news2024/11/22 17:43:23

基本介绍

sqlpp11 是 C++ 的类型安全的 SQL 模版库。

Sqlpp11的官方下载地址是,

GitHub - rbock/sqlpp11: A type safe SQL template library for C++

在这里,可以找到官方的详细介绍文档,

https://github.com/rbock/sqlpp11/tree/main/docs

作者在介绍页面上是这样描述sqlpp11的,

A type safe embedded domain specific language for SQL queries and results in C++.

在C++领域,用于 SQL 查询及结果检查的类型安的全嵌入式域特定语言。

这句话到底是什么意思呢?

我们知道,SQL 和 C++ 都是强类型语言。 尽管如此,大多数 C/C++ 的 SQL 接口都是基于将查询语句构造为字符串并将数组或字符串映射解释为结果;也就是说,用户其实是使用字符串对数据库进行操作。

然而,人们更期望在进行SQL操作时能更自然地,或者说更符合人们习惯地使用类型检查,并对数据库进行操作。

sqlpp11 是一个嵌入式领域特定语言 (EDSL) 的模板库,它允许用户,

  1. 定义表示表和列的类型,
  2. 构造类型安全查询,在编译时检查语法错误、类型错误、名称错误甚至一些语义错误,
  3. 通过使用适当命名和类型化的成员,迭代特定的查询的结构,以解释最终结果。

这带来了几个好处,例如

  1. 库用户可以轻松地操作结构和函数,
  2. 编译器早在代码进入单元测试或生产之前就报告了多种错误,
  3. 该库隐藏了用于查询和解释 select 调用返回结果的字符串构造的细节。

该库支持静态和动态查询。 前者在类型和一致性检查方面提供了更大的好处。 后者使得构建运行中的查询更加容易。

sqlpp11 的核心是供应商中立的。 数据库的特定特征(例如不支持或非标准功能)由连接器库处理。 连接器库可以在编译时通知开发人员缺少的功能。 他们还会在需要时专门解释表达式。 例如,连接器可以使用运算符|| 或者用于字符串连接的 concat 方法,而无需开发人员更改语句。

此存储库中包含 MariaDB、MySQL、PostgreSQL、sqlite3、sqlcipher 的连接器。

作者同时也说明,该库已经在生产中使用,但不算完全完成。

下面,我们简单地用一个MySQL的例子介绍一下,如何使用这个模板库。网上有人举了个sqlite3的例子,

C++ ORM框架:SQLPP11教程-CSDN博客

对应地,我们在这里改成MySQL的例子。

下载sqlpp11项目

首先是到官方的github网址上把项目拉下来,使用他的最新版v0.64,本地库命名为sqlpp11v064,如下,

git clone --recursive GitHub - rbock/sqlpp11: A type safe SQL template library for C++  -b v0.64  sqlpp11v064

因为sqlpp11依赖date库,本来希望recursive把库拉到适当的地方,最后使用cmake后,发现data下载到了项目的_deps中,

Cmake配置(Configure)后生成(Generate)项目,最后就可以用vs2019打开项目进行编译了。就我这里的配置而方,date的位置是在,

D:\vQt2024SQL\devSqlpp11v064\_deps\date-src\include

当然你也可以单独到这里下载,

GitHub - HowardHinnant/date: A date and time library based on the C++11/14/17 <chrono> header

要说明的是,sqlpp11本身是不需要编译的,她只有一些头文件,编译出来的其实都是一些测试可执行文件。

例如,测试mysql的sample所需要的sql文件在这里,

D:\vQt2024SQL\sqlpp11v064\tests\mysql\usage\TabSample.sql

生成的结果在这里,

D:\vQt2024SQL\sqlpp11v064\tests\mysql\usage\TabSample.h

如果你运行sqlpp11_mysql_tests这个项目,实际就是对该数据库进行测试操作,如下,

这里我们不对sqlpp11的官方测试代码进行过多的解读,只是简单以MySQL为例介绍一下使用方法。

创建测试项目

我们用vs2019新建一个sqlpp11Test01的项目。

首先,项目的路径依赖必须正确,依上所述,这里的路径依赖是,

D:\vQt2024SQL\sqlpp11v064\include;

D:\vQt2024SQL\devSqlpp11v064\_deps\date-src\include;

C:\Program Files\MySQL\MySQL Server 8.0\include;

库依赖只有libmysql,如下,

C:\Program Files\MySQL\MySQL Server 8.0\lib\libmysql.lib;

生成SQL表的C++源码

假设我们需要进行操作的表格有以下SQL结构,

CREATE TABLE Student (
name  TEXT,
age   INTEGER
);

源码生成工具ddl2cpp在sqlpp11的scripts下面,

D:\vQt2024SQL\sqlpp11v064\scripts\ddl2cpp,

这里我们直接使用该工具生成Student.h文件,使用的指令为

python ddl2cpp Student.sql ./Student TestProject 

 

然后就可以看到头文件Student.h生成了,如下,

#pragma once

// generated by ddl2cpp Student.sql ./Student TestProject

#include <sqlpp11/table.h>
#include <sqlpp11/data_types.h>
#include <sqlpp11/char_sequence.h>

namespace TestProject
{
  namespace Student_
  {
    struct Name
    {
      struct _alias_t
      {
        static constexpr const char _literal[] =  "name";
        using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
        template<typename T>
        struct _member_t
          {
            T name;
            T& operator()() { return name; }
            const T& operator()() const { return name; }
          };
      };
      using _traits = sqlpp::make_traits<sqlpp::text, sqlpp::tag::can_be_null>;
    };
    struct Age
    {
      struct _alias_t
      {
        static constexpr const char _literal[] =  "age";
        using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
        template<typename T>
        struct _member_t
          {
            T age;
            T& operator()() { return age; }
            const T& operator()() const { return age; }
          };
      };
      using _traits = sqlpp::make_traits<sqlpp::integer, sqlpp::tag::can_be_null>;
    };
  } // namespace Student_

  struct Student: sqlpp::table_t<Student,
               Student_::Name,
               Student_::Age>
  {
    struct _alias_t
    {
      static constexpr const char _literal[] =  "Student";
      using _name_t = sqlpp::make_char_sequence<sizeof(_literal), _literal>;
      template<typename T>
      struct _member_t
      {
        T Student;
        T& operator()() { return Student; }
        const T& operator()() const { return Student; }
      };
    };
  };
} // namespace TestProject

测试简单的增删改查操作

源码如下,

#include "sqlpp11/sqlpp11.h"
#include "sqlpp11/mysql/mysql.h"
#include "Student.h"
#include <sstream>
#include <stdlib.h>

struct DEFECTINFO {
    int id;
    int type;
    std::string spath;
    std::string spos;
};

int main(void)
{
	sqlpp::mysql::connection_config myconfig;
    myconfig.host = "localhost";
    myconfig.user = "root";
    myconfig.password = "";
    myconfig.database = "sqlpp_mysql";
    myconfig.debug = true;

	try
	{
		sqlpp::mysql::connection db(myconfig);

		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");
}

测试结果的输出如下,

使用MySQL workbend打开数据库,看到的结果如下,

本文结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1374362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解锁Python库中操作系统级别模块psutil

目录 一、psutil库简介 二、安装psutil库 三、获取系统信息 1、获取CPU信息&#xff1a; 2、获取内存信息&#xff1a; 3、获取磁盘信息&#xff1a; 4、获取网络信息&#xff1a; 四、进程管理 五、系统信息和监控 六、总结 随着Python的普及&#xff0c;越来越多的…

nuxt pm2使用、启动、问题解决方案

pm2简介 pm2是一个进程管理工具,可以用它来管理node进程&#xff0c;并查看node进程的状态&#xff0c;当然也支持性能监控&#xff0c;进程守护&#xff0c;负载均衡等功能&#xff0c;在前端和nodejs的世界中用的很多 pm2安装 安装pm2: $ npm install -g pm2查看pm2的安装…

iPad Pro如何使用SSH远程连接服务器云端编程开发【内网穿透】

文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. 配置固定TCP端口地址4.1 保留固定TCP地址4.2 配置固定的TCP端口地址4.3 使用固定TCP地址远程vscode 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 …

JavaScript 增加数组中指定元素(5种方法)

、 文章目录 目录 文章目录 前言 一、数组是什么&#xff1f; 二、数组增步骤 总结 前言 在现代的Web开发中&#xff0c;JavaScript是一种不可或缺的编程语言。它具有强大的功能和灵活的语法&#xff0c;使得开发人员能够轻松地处理各种任务。其中&#xff0c;处理数组是JavaS…

基于JavaWeb+BS架构+SpringBoot+Vue基于web的多媒体素材管理系统的设计和实现

基于JavaWebBS架构SpringBootVue基于web的多媒体素材管理系统的设计和实现 文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 文末获取源码 Lun文目录 1 绪 论 1 1.1选题背景与意义 1 1.1 研究背景 1 1.2 研究意义…

Python办公自动化 – 数据预处理和数据校验

Python办公自动化 – 数据预处理和数据校验 以下是往期的文章目录&#xff0c;需要可以查看哦。 Python办公自动化 – Excel和Word的操作运用 Python办公自动化 – Python发送电子邮件和Outlook的集成 Python办公自动化 – 对PDF文档和PPT文档的处理 Python办公自动化 – 对Ex…

网络基础学习(3):交换机

1.交换机结构 &#xff08;1&#xff09;网线接口和后面的电路部分加在一起称为一个端口&#xff0c;也就是说交换机的一个端口就相当于计算机上的一块网卡。 如果在计算机上安装多个网卡&#xff0c;并让网卡接收所有网络包&#xff0c;再安装具备交换机功能的软件&#xff0…

QT开发 2024最新版本优雅的使用vscode开发QT

▬▬▬▬▬▶VS开发QT◀▬▬▬▬▬ &#x1f384;先看效果 &#x1f384;编辑环境变量 如图添加环境变量&#xff01;&#xff01;&#xff01; 东西全在QT的安装目录&#xff01;&#xff01;&#xff01; 找到的按照我的教程再装一次&#xff01;&#xff01;&#xff01; 点…

文心一言 VS 讯飞星火 VS chatgpt (176)-- 算法导论13.3 5题

五、用go语言&#xff0c;考虑一棵用 RB-INSERT 插人 n 个结点而成的红黑树。证明&#xff1a;如果 n>1&#xff0c;则该树至少有一个红结点。 文心一言&#xff1a; 要证明这个问题&#xff0c;我们首先需要理解红黑树的性质。红黑树是一种自平衡二叉搜索树&#xff0c;它…

test Property-based Testing-03-QuickTheories Java的属性驱动测试框架入门介绍

拓展阅读 开源 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) 开源 Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) QuickTheories QuickTheories 是针对Java 8的属性驱动测试框架。 如果你…

python代码练习:双指针法

题目一&#xff1a;移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…

源码:RecyclerView核心知识点

一、简单使用 1.导包 implementation androidx.recyclerview:recyclerview:1.1.0 2.使用 mAdapter new MyAdapter(getActivity());LinearLayoutManager layoutManager new LinearLayoutManager(getActivity());//设置布局方向// layoutManager.setOrientation(LinearLayoutM…

第十一章 后端编译与优化

文章目录 11.1 概述11.2 即时编译器11.2.1 解释器与编译器11.2.2 编译对象与触发条件11.2.3 编译过程 11.3 提前编译器11.4 编译器优化技术11.4.1 方法内联11.4.2 逃逸分析11.4.3 公共子表达式11.4.4 数组边界检查消除 11.1 概述 如果我们把字节码看作是程序语言的一种中间表示…

哈希应用之位图+布隆过滤器

文章目录 bitset介绍bitset常用函数位图的简单实现布隆过滤器布隆过滤器实现 bitset介绍 在 C 中&#xff0c;std::bitset 是一个标准库提供的类模板&#xff0c;用于表示固定大小的位集合。std::bitset 类模板允许你以一种方便且高效的方式处理位&#xff08;二进制位&#x…

外汇天眼:什么是外汇隔夜利息、滑点和价格跳空?

隔夜利息 所有的外汇交易中只要持仓过夜就一定会有隔夜利息&#xff0c;只不过这个利息有可能是正的&#xff0c;也有可能是负数。 买一个货币涨&#xff0c;相当于我们卖出对应货币&#xff0c;买入基础货币。 买一个货币跌&#xff0c;相当于我们向外汇平台卖出基础货币&a…

定制耐酸碱移液吸头PFA移液枪头可重复使用

移液枪是移液器的一种&#xff0c;常用于实验室少量或微量液体的移取&#xff0c;规格不同&#xff0c;不同规格的移液枪配套使用不同大小的枪头&#xff0c;不同生产厂家生产的形状也略有不同&#xff0c;但工作原理及操作方法基本一致。移液枪属精密仪器&#xff0c;使用及存…

开启鸿蒙开发探索之旅ArkTS基本语法介绍(3)

上一章简单的介绍了鸿蒙HUAWEI DevEco Studio框架的搭建&#xff0c;这一章讲一下鸿蒙的主要开发一眼ArkTS的基本语法结构 1.ArkTS语法解释 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript&#xff08;简称TS&#xff09;生态基础上做了进一步扩展&…

Redis的主从配置,哨兵模式,集群模式

目录 什么是主从复制&#xff1f; 主从复制的作用&#xff1f; 主从复制的流程&#xff1f; 搭建Redis的主从复制 安装Redis 环境准备 修改内核参数 安装Redis 定义systemd服务管理脚本 修改Redis配置文件&#xff08;Master节点操作&#xff09;192.168.17.25 修改Re…

计算机网络技术-2022期末考试解析

【前言】 这是计算机网络技术这门课&#xff0c;感觉和计网还是有不一样的&#xff0c;但也有能做的&#xff0c;把能做的做了。 一、单项选择题&#xff08;每题2分&#xff0c;共20分&#xff09; 1. 用于测试两台计算机连通状况的命令是 。 ( ) A. cmd B. ping C. ipconf…

(N-137)基于springboot,vue运动会报名管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueAvueElementUI 服务端技术&#xff1a;springbootmybatis 本项…