QT QxOrm CRUD增删改查mysql数据库操作

embedded/2024/9/19 18:41:21/ 标签: 数据库, mysql

QT QxOrm CRUD增删改查mysql数据库操作
QxOrm 是一个 C++ 库,旨在为 C++ 用户提供对象关系映射 (ORM) 功能。
基于每个类的简单 C++ 设置函数(如 Java 中的 Hibernate XML 映射文件),QxOrm 库提供以下功能:
持久性: 支持最常见的数据库,如 SQLite、MySQL、PostgreSQL、Oracle、MS SQL Server、MongoDB(具有 1-1、1-n、n-1 和 n-n 关系)
序列化: JSON、二进制和 XML 格式;
反射(或自省): 动态访问类定义、检索属性和调用类方法
HTTP Web 服务器: 独立的多线程 HTTP 1.1 Web 服务器(支持 SSL/TLS、持久连接、cookie、会话、分块响应、URL 调度程序/路由)

by txwtech
JSON API: 与 C++/Qt 以外的其他技术(REST Web 服务、QML 应用程序、脚本语言)的互操作性。
QxOrm 依赖于 Qt(从 4.5.0 版开始)和 boost(从 1.38 版开始,默认情况下只需要头文件 *.hpp)

下载源码

 参考:

https://www.cnblogs.com/txwtech/p/18361998

打开pro文件 


 

编译完成后生成dll:

 

新建qxormtest项目测试程序

 

配置pro文件,对应QxOrm1.5存放路径进行相应修改

QT += core gui
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17
QMAKE_PROJECT_DEPTH = 0
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \book.cpp \main.cpp \mainwindow.cppHEADERS += \book.h \export.h \mainwindow.h \precompiled.hFORMS += \mainwindow.ui
DEFINES += _BUILDING_QX_BOOK #通过它可以知道项目是否正在编译
#include(./QxOrm/QxOrm.pri)
#include(D:/QT_Project/QxOrm-master/QxOrm/QxOrm.pri)
include(D:/QT_Project/QxOrm_1.5.0/QxOrm-master/QxOrm.pri)
# 设置好QxOrm链接库目录和文件包含
INCLUDEPATH += D:/QT_Project/QxOrm_1.5.0/QxOrm-master/include
LIBS += -LD:\QT_Project\QxOrm_1.5.0\QxOrm-master\lib# 设置好QxOrm对应的动态链接库CONFIG(debug, debug|release) {TARGET = qxormtestLIBS += -l"QxOrmd"} else {TARGET = qxormtestLIBS += -l"QxOrm"})
# 定义好预编译文件
!contains(DEFINES, _QX_NO_PRECOMPILED_HEADER) {
PRECOMPILED_HEADER = ./precompiled.h
} # !contains(DEFINES, _QX_NO_PRECOMPILED_HEADER)# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QList>
#include "book.h"
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
//#include "precompiled.h"
//#pragma execution_character_set("utf-8")
#pragma execution_character_set("utf-8")MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         获取现在可用的数据库驱动
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/qDebug() << "Available drivers:";QStringList drivers = QSqlDatabase::drivers();  //foreach(QString driver, drivers)qDebug() << driver;// connect_mysql();/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         连接数据库
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/qx::QxSqlDatabase::getSingleton()->setDriverName("QMYSQL");			//这里可以是任意支持的数据库驱动qx::QxSqlDatabase::getSingleton()->setDatabaseName("book_store_db");qx::QxSqlDatabase::getSingleton()->setHostName("localhost");qx::QxSqlDatabase::getSingleton()->setUserName("root");qx::QxSqlDatabase::getSingleton()->setPassword("87958868");qx::QxSqlDatabase::getSingleton()->setPort(3306);qx::QxSqlDatabase::getSingleton()->setFormatSqlQueryBeforeLogging(true);qx::QxSqlDatabase::getSingleton()->setDisplayTimerDetails(true);QSqlError sqlError;QSqlDatabase db = qx::QxSqlDatabase::getDatabase();// 检查连接是否有效if (db.isValid()){qDebug() << "mysql connection is ok数据库连接成功!";if (sqlError.type() == QSqlError::NoError){// qDebug() << "表创建成功!";}else{//  qDebug() << "表创建失败! 错误信息: " << sqlError.text();}}else{sqlError = db.lastError();  // 获取最后一次数据库错误信息qDebug() << "mysql connection is false,数据库连接失败!";qDebug() << "错误信息: " << sqlError.text();}QSqlError daoError;QList<book> list_of_book;// 尝试从数据库中获取所有的 book 记录daoError = qx::dao::fetch_all(list_of_book);if (daoError.type() == QSqlError::NoError){qDebug() << "数据查询成功!";// 遍历 QList<book>for (const book& book2 : list_of_book){qDebug() << "ID: " << book2.id << ", Name: " << book2.book_name << ", isbn: " << book2.book_ibsn<<",price:"<<book2.book_price;// 在这里可以执行其他操作}}else{qDebug() << "查询所有数据失败! 错误信息: " << daoError.text();}/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         查询
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************///第一种方法-执行原生的sql语句List_book list_book;// qx_query querySql("select * from user");// daoError = qx::dao::execute_query(querySql, list_user);// List_user::iterator it = list_user.begin();//  while(it != list_user.end()){// qDebug() << "id:" << it.i->t().second->id;// qDebug() << "name:" << it.i->t().second->name;// qDebug() << "age:" << it.i->t().second->age;// qDebug() << "capacity:" << it.i->t().second->capacity;// it++;// }//第二种方法-fetch_xxx//qx::dao::fetch_all(list_book);// 当然还有其他很多函数:fetch_by_id(),fetch_by_query()....//占位符形式//QList<book> list_of_book;qx::QxSqlQuery query("WHERE book_name = :book_name");   //默认前面是 select * from userquery.bind(":book_name","语文");daoError = qx::dao::fetch_by_query(query,list_of_book);for (long l = 0; l < list_of_book.count(); l++){/* here we can work with the collection provided by database */qDebug()<<"yuwen query:"<<list_of_book[l].book_name<<",price:"+list_of_book[l].book_price;}//占位符的变体qx_query query2;query2.where("book_ibsn").startsWith("isbn").and_("book_price").isGreaterThan(10).and_("book_price").isLessThan(30);daoError = qx::dao::fetch_by_query(query2,list_of_book);qDebug()<<"书本序号开始查找:";for (long l = 0; l < list_of_book.count(); l++){/* here we can work with the collection provided by database */qDebug()<<list_of_book[l].book_name<<"isbn:"<<list_of_book[l].book_ibsn<<",price:"+list_of_book[l].book_price;}//查询自己关心的字段,默认是查询指定表的所有列,指定关系可以查询自己指定的列//定义一个关系QStringList relations = QStringList() << "-{book_ibsn,book_price}" << "{book_name}";//获取感兴趣的属性(name,capacity),如果没有关系默认是查询一个表的所有列数据,如果在{}前面加-,表示不要此属性qx::dao::fetch_by_query_with_relation(relations,query2,list_of_book);qDebug()<<"仅仅显示书名:";for (long l = 0; l < list_of_book.count(); l++){/* here we can work with the collection provided by database */qDebug()<<list_of_book[l].book_name<<"isbn:"<<list_of_book[l].book_ibsn<<",price:"+list_of_book[l].book_price;}/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         添加数据
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/typedef QSharedPointer<book> bk_ptr;bk_ptr bk1;bk1.reset(new book());bk1->book_name="yuwen11";bk1->book_ibsn ="yusn001";bk1->book_price ="32.1";bk_ptr bk2;bk2.reset(new book());bk2->book_name="yuwen22";bk2->book_ibsn ="yusn002";bk2->book_price ="33.1";//qvector存放book的智能指针typedef QVector<bk_ptr> book_vec;book_vec bk_vec;bk_vec.push_back(bk1);bk_vec.push_back(bk2);daoError = qx::dao::insert(bk_vec);if(daoError.type()==QSqlError::NoError){qDebug()<<"数据添加成功";}else{qDebug()<<"数据添加失败"<<daoError.text();}/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         删除数据
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/book del_bookInfo;del_bookInfo.id=12;daoError = qx::dao::delete_by_id(del_bookInfo);if(daoError.type()==QSqlError::NoError){qDebug()<<"数据删除成功";}else{qDebug()<<"数据删除失败"<<daoError.text();return;}//条件删除:qx::QxSqlQuery condition_query("WHERE book_name = 'yuwen1'");daoError = qx::dao::delete_by_query<book>(condition_query);
/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         修改数据 by id
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/book bookInfo;bookInfo.id=10;daoError = qx::dao::fetch_by_id(bookInfo);if(daoError.type()==QSqlError::NoError){qDebug()<<"数据查询成功";}else{qDebug()<<"数据查询失败"<<daoError.text();return;}bookInfo.book_name="语文3";bookInfo.book_price="99.99999";daoError = qx::dao::update(bookInfo);if(daoError.type()==QSqlError::NoError){qDebug()<<"数据更新成功";}else{qDebug()<<"数据更新失败"<<daoError.text();return;}/**********************************************
* @projectName   %{CurrentProject:Name}
* @brief         修改数据 by bookname
* @param         void
* @return        void
* @author        cdtxw@foxmail.com/ by txwtech
* @date          2024-08-27
**********************************************/book bookInfo2;// qx::QxSqlQuery query_mo("WHERE book_name = :book_name");   //默认前面是 select * from userqx::QxSqlQuery query_mo("WHERE book_name = 'yuwen2'");//query_mo.bind(":book_name","yuwen2");qx_query qx2;qx2.where("book_name").isEqualTo("yuwen2");daoError = qx::dao::fetch_by_query(query_mo,list_of_book);//bookInfo2.id =18;//bookInfo2.book_name = "yuwen2b";bookInfo2.book_price="6.661";QStringList aa={"book_price"};daoError = qx::dao::update_by_query(query_mo,bookInfo2,NULL,aa,true);//测试未修改成功,待分析//QStringList relations3 = QStringList() << "-{id,book_ibsn,name}" << "{book_price}";//获取感兴趣的属性(name,capacity),如果没有关系默认是查询一个表的所有列数据,如果在{}前面加-,表示不要此属性// daoError = qx::dao::update_by_query_with_relation(relations3,query_mo,bookInfo2);//qx::dao::save 和 qx::dao::insert都可以进行插入,区别在于如果save的数据的id是存在的则修改数据// bookInfo2.id =2;// bookInfo2.book_name = "art2";// qx::dao::save(bookInfo2);//普通查询语句QString price_value ="7.78";QString com_sql =QString("UPDATE book_info SET book_ibsn='ibsn1',book_price='%1' WHERE book_name='yuwen2'").arg(price_value);qx_query querySql_normal(com_sql);daoError = qx::dao::execute_query(querySql_normal,bookInfo2);if(daoError.type()==QSqlError::NoError){qDebug()<<"数据更新成功by bookname";}else{qDebug()<<"数据更新失败by book name"<<daoError.text();return;}}void MainWindow::connect_mysql()
{db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("localhost");db.setPort(3306);db.setDatabaseName("book_store_db");db.setUserName("root");db.setPassword("123456");if (!db.open()) {qDebug("Sql connect failed.");qDebug() << db.lastError().text();} else {qDebug("Sql connected.");}query=QSqlQuery(db);QString sq="INSERT INTO db_mysql VALUES(0,'ttxsss', 123, '很好', 60, 0);";bool res=query.exec(sq);if(!res){qDebug()<<"添加失败";}else{qDebug()<<"添加成功";}
}\
MainWindow::~MainWindow()
{delete ui;
}

 建立数据库映射

book.h

// book.h
#ifndef BOOK_H
#define BOOK_H
//#include "precompiled.h"    //带有 '#include <QxOrm.h>' 和 '#include "export.h"' 的预编译头文件
//#include <QxOrm_Impl.h>class QX_BOOK_DLL_EXPORT book
//class QX_DLL_EXPORT_HELPER book
{//在 QxOrm 上下文中注册的 4 个属性id,name,age,capacity
public:int id;QString book_name;//int age;//double capacity;QString book_ibsn;QString book_price;book(): id(1){;} //初始化id为1virtual ~book(){;}
};QX_REGISTER_PRIMARY_KEY(book, int)  // 定义主键的类型/**QX_REGISTER_HPP_QX_DEMO宏是在 QxOrm 上下文中注册 'BOOK' 类所必需的参数 1:要注册的当前类 => 'BOOK'参数 2 : 基类,如果没有基类,使用 qx trait => 'qx::trait::no_base_class_defined'参数 3 : 序列化引擎用来提供“上升兼容性”的类版本
*/
QX_REGISTER_HPP_QX_BOOK(book, qx::trait::no_base_class_defined, 0)typedef std::shared_ptr<book> book_ptr;
typedef qx::QxCollection<int, book_ptr> List_book;#endif // BOOK_H

cpp

#include "precompiled.h"    //带有 '#include <QxOrm.h>' 和 '#include "export.h"' 的预编译头文件
#include "book.h"
#include <QxOrm_Impl.h>     // 自动内存泄漏检测和提升序列化导出宏QX_REGISTER_CPP_QX_BOOK(book)    // 这个宏是在 QxOrm 上下文中注册 'User' 类所必需的namespace qx
{template <> void register_class(QxClass<book> &t){t.setName("book_info");  // 'User' C++ 类映射到 'user' 数据库表t.id(&book::id, "id");  // Register 'User::id' <=> primary key in your databaset.data(&book::book_name, "book_name");  // Register 'User::age' property mapped to 'age' database column namet.data(&book::book_ibsn, "book_ibsn"); // Register 'User::name' property mapped to 'name' database column namet.data(&book::book_price, "book_price");    // Register 'User::capacity' property mapped to 'capacity' database column name}}

export.h

#ifndef EXPORT_H
#define EXPORT_H#ifdef _BUILDING_QX_BOOK
#define QX_BOOK_DLL_EXPORT QX_DLL_EXPORT_HELPER
#else
#define QX_BOOK_DLL_EXPORT QX_DLL_IMPORT_HELPER
#endif#ifdef _BUILDING_QX_BOOK
#define QX_REGISTER_HPP_QX_BOOK QX_REGISTER_HPP_EXPORT_DLL
#define QX_REGISTER_CPP_QX_BOOK QX_REGISTER_CPP_EXPORT_DLL
#else
#define QX_REGISTER_HPP_QX_BOOK QX_REGISTER_HPP_IMPORT_DLL
#define QX_REGISTER_CPP_QX_BOOK QX_REGISTER_CPP_IMPORT_DLL
#endif#endif // EXPORT_H

PRECOMPILED.h预编译文件

#ifndef PRECOMPILED_H
#define PRECOMPILED_H#include <QxOrm.h>
#include "export.h"#endif // PRECOMPILED_H

 数据库

测试结果:

打印输出

QT5.15.2加载mysql驱动-QMYSQL driver not loaded解决方法_qt加载mysql-CSDN博客

工程代码:

https://download.csdn.net/download/txwtech/89720062


http://www.ppmy.cn/embedded/110736.html

相关文章

利用TCP编程实现FTP功能

模拟FTP核心原理&#xff1a;客户端连接服务器后&#xff0c;向服务器发送一个文件。文件名可以通过参数指定&#xff0c;服务器端接收客户端传来的文件&#xff08;文件名随意&#xff09;&#xff0c;如果文件不存在自动创建文件&#xff0c;如果文件存在&#xff0c;那么清空…

springboot集成Hystrix

在分布式系统中&#xff0c;随着服务之间的调用链变得越来越复杂&#xff0c;系统的稳定性和可用性面临更多挑战。例如&#xff0c;某个微服务可能由于故障或延迟&#xff0c;导致请求被阻塞甚至失败&#xff0c;从而影响整个系统的可用性。Netflix Hystrix 是一种容错框架&…

Nginx怎么重新编译添加模块

转自 https://www.php.cn/faq/547300.html

uni-app plus.runtime.arguments 获取参数

uni-app plus.runtime.arguments 获取参数 问题 在 app.vue 中 onShow 获取 应用启动的参数:plus.runtime.arguments 这个是可行的. APP打开以后, 进入到了后台 然后再恢复到前台 仍然会走一次 onShow的生命周期 然后获取到plus.runtime.arguments 中的参数, 那么这参数就是…

轮询解决方案

概述 轮询的使用场景&#xff1a; 股票 K 线图聊天重要通知&#xff0c;实时预警 这些场景都是都要实时性的。 http 是请求响应模式&#xff0c;一定需要先请求&#xff0c;后响应。 解决方案&#xff1a; 短轮询&#xff1a;interval 定时发送请求。问题&#xff1a;大量…

echart图表组件封装(vue3)

组件封装&#xff1a; <template><div class"echart-container"><div class"chart" ref"chartRef"></div></div> </template><script lang"ts" setup>import { ref, nextTick, onMounted…

Linux_kernel原理08

一、温故知新 系统移植 1、uboot uboot主要做两件事&#xff1a;1、负责初始化硬件&#xff1b;2、负责引导操作系统的启动 2、Linux内核 Linux内核的五大功能 【1】进程间通信 【2】进程管理 【3】网络子系统 【4】虚拟文件子系统 【5】内存管理 3、根文件系统 当Linux内核启动…

中原地产:人力资源数字化创新实践分享

近日&#xff0c;法大大与人力资源智享会&#xff08;以下简称“智享会”&#xff09;联合发布了《第七届人力资源共享服务中心研究报告》&#xff08;点击阅读及下载&#xff1a;最新&#xff01;《第七届人力资源共享服务中心研究报告》重磅来袭&#xff09;&#xff0c;该报…

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录 [web][极客大挑战 2019]Http 考点&#xff1a;Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点&#xff1a;弱密码字典爆破 四种方法&#xff1a; [web][极客大挑战 2019]Http 考点&#xff1a;Referer协议、UA协议、X-Forwarded-For协议 访问…

Linux运维_Bash脚本_源码编译Moby(Docker-CE)-20240803

Linux运维_Bash脚本_源码编译Moby(Docker-CE)-20240803 Bash (Bourne Again Shell) 是一个解释器&#xff0c;负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件&#xff0c;并于 1989 年发布的免费软件&#xff0c;作为 Sh (Bourne Shell) 的替代品。 您可…

flink中disableOperatorChaining() 的详解

在 Apache Flink 中&#xff0c;disableOperatorChaining() 是一个用于全局禁止算子链式合并的方法。与 disableChaining() 不同&#xff0c;disableChaining() 只是作用于某个具体的算子&#xff0c;而 disableOperatorChaining() 则会全局禁止链式合并&#xff0c;确保所有算…

10个Python办公自动化案例

文章目录 系列目录10个Python办公自动化案例1. Excel数据读取与写入2. 自动生成PDF文件3. 自动发送邮件4. 自动化文件重命名5. 批量下载网页内容6. 自动化数据可视化7. 自动化文档批量处理8. 批量文件压缩9. 日程提醒自动化10. 数据定时备份 系列目录 序号直达链接表白系列1Pyt…

使用Frida 定位发送请求位置

对于App逆向时&#xff0c;时常不知道如何定位网络请求代码的发出位置&#xff0c;部分情况都是使用自定义框架开发的&#xff0c;想要快速定位这部分就得使用Frida 对JNI的string函数进行hook&#xff0c;看看是不是能再调用栈的位置能够找到。 function hookNewStringUTF() …

VSCode 创建Python 项目(最简单,最少步骤,无痛从pycharm迁移项目)

第一步&#xff1a;下载 下载地址&#xff1a;https://code.visualstudio.com/docs/?dvwin64user 第二步&#xff1a;配置 2.1&#xff1a;VsCode设置中文 按住键盘上的“CtrlShiftP”组合键&#xff0c;打开命令面板。 在命令面板中输入“Configure Display Language”。点击…

算法岗/开发岗 实况

深信服算法岗一面 第一题 树的直径有哪些解法 两次dfs和树形dp&#xff0c;讲了一下树形dp的思路 因为我的简历写的比较少&#xff0c;所以面试官问我一些个人信息和擅长哪方面。 我说&#xff1a;ACM大一下打到大三&#xff0c;然后去考研。dp写的多一点&#xff0c;还有思维…

MySQL日志

MySQL日志 文章目录 MySQL日志MySQL三大日志binlog的三种格式 redo log 和 binlog的区别和应用场景为什么崩溃恢复不用binlog而用redo log&#xff1f; redo log如何实现持久化redo log还能做什么&#xff1f;redo log的三种刷盘策略 两阶段提交什么是&#xff1f;为什么&#…

​招​银​网​络​​大​疆​​元​象​一​面​

1. 请尽可能详细地说明&#xff0c;XHR、axios和fetch这三者的区别是什么&#xff1f;axios和fetch的底层实现是什么&#xff1f;axios拦截器是什么&#xff1f;axios提供了哪些配置或功能&#xff0c;是fetch和XHR中没有的&#xff1f;你的回答中不要写出示例代码。 XHR、axi…

3.Kubernetes资源对象之pod

&#x1f482; 个人主页: Java程序鱼 &#x1f4ac; 如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏(一键三连)和订阅专栏 &#x1f464; 微信号&#xff1a;hzy1014211086&#xff0c;想加入技术交流群的小伙伴可以加我好友&#xff0c;群里会分享学习资料、学习方法…

k8s API资源对象ingress

有了Service之后&#xff0c;我们可以访问这个Service的IP&#xff08;clusterIP&#xff09;来请求对应的Pod&#xff0c;但是这只能是在集群内部访问。 要想让外部用户访问此资源&#xff0c;可以使用NodePort&#xff0c;即在node节点上暴漏一个端口出来&#xff0c;但是这…

【2024 版】最新 kali linux 入门及常用简单工具介绍(非常详细)

一、介绍 kali Linux Kali Linux 是一个基于 Debian 的 Linux 发行版&#xff0c;主要用于数字取证和渗透测试。它预装了大量的安全审计和渗透测试工具&#xff0c;被广泛应用于网络安全领域。 &#xff08;一&#xff09;特点 工具丰富&#xff1a;集成了数百种用于渗透测试…