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 += widgets
CONFIG += 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.0
SOURCES += \
book.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
book.h \
export.h \
mainwindow.h \
precompiled.h
FORMS += \
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 = qxormtest
LIBS += -l"QxOrmd"
} else {
TARGET = qxormtest
LIBS += -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 user
query.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 user
qx::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("87958868");
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为1
virtual ~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 database
t.data(&book::book_name, "book_name"); // Register 'User::age' property mapped to 'age' database column name
t.data(&book::book_ibsn, "book_ibsn"); // Register 'User::name' property mapped to 'name' database column name
t.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