Qt-链接数据库可视化操作

news2024/11/23 22:09:59

1. 概述

  • Qt 能够支持对常见数据库的操作,例如: MySQL、Oracle、SqlServer 等等。

  • Qt SQL模块中的API分为三层:驱动层、SQL接口层、用户接口层。

    • 驱动层为数据库和SQL接口层之间提供了底层的桥梁。

    • SQL接口层提供了对数据库的访问,包括 创建 / 删除库、表,执行增删改查的SQL语句。

    • 用户接口层提供了一种更加简便的方式将数据库中的数据链接到窗口部件上。

分层
驱动层QSqlDriver、QSqlDriverCreator、QSqlDriverCreatorBase、QSqlDriverPlugin和QSqlResult
SQL接口层QSqlDatabase、QSqlQuery、QSqlError、QSqlField、QSqlIndex和QSqlRecord
用户接口层QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel

2. 准备工作

  1. 创建项目,并在 .pro 文件中加入 sql 模块: QT += core gui sql

  2. 将 MySQL目录中的 libmysql.dll 和 libmysql.lib 文件复制到 Qt\5.12.3\mingw73_32\bin 目录下

如果不行,则去官网自己找 : MySQL :: Download MySQL Connector/C (Archived Versions)icon-default.png?t=O83Ahttps://downloads.mysql.com/archives/c-c/  

3. 链接数据库

  • Qt 默认支持一些驱动,可以通过 QSqlDatabase::drivers() 方法查看Qt支持的驱动类型。

  • 链接到数据库服务器需要使用 QSqlDatabase 类

  • 主要方法:

    • QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 链接MySQL服务器

    • db.setHostName("127.0.0.1"); // 设置服务器地址

    • db.setPort(3306); // 设置端口号,如果使用默认端口号可不调用该方法

    • db.setUserName("root"); // 设置用户名

    • db.setPassword("root"); // 设置密码

    • db.setDatabaseName("study"); // 设置要操作的数据库

    • db.open() // 打开数据库链接,返回值 bool

  • 其他方法

    • db.lastError(); // 获取上一次的错误信息, 返回一个 QSqlError 对象,调用 text() 方法转为字符串

#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 打印支持的数据库驱动
    qDebug() << QSqlDatabase::drivers();

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("127.0.0.1");
    db.setPort(3306);
    db.setUserName("root");
    db.setPassword("root");
		db.setDatabaseName("study");

    // 当数据库打开失败时,提示信息
    if(db.open())
    {
        qDebug() << "链接成功";
    }
    else
    {
        qDebug() << "链接失败" << db.lastError().text();
    }
}

4. 执行SQL语句

  • 执行 SQL 语句需要依靠 QSqlQuery 类

    • exec(QString sql) 方法用来执行sql语句

    • prepare() 方法执行预处理

    • execBatch() 执行预处理的SQL语句

1)创建库 (创建库)

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
  ui->setupUi(this);

  // 打印支持的数据库驱动
  qDebug() << QSqlDatabase::drivers();

  QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
  db.setHostName("127.0.0.1");
  db.setPort(3306);
  db.setUserName("root");
  db.setPassword("root");

  // 当数据库打开失败时,提示信息
  if (!db.open())
  {
    QMessageBox::critical(this, "警告", db.lastError().text());
    return ;
  }

  // 创建 QSqlQuery 对象
  QSqlQuery query;

  query.exec("create database abc");      // 创建库

}

 2)删除库

query.exec("drop database abc"); 

3)创建表

query.exec(
  "create table student( \
     sno int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, \
     sname varchar(30) not null unique, \
     sage  tinyint UNSIGNED, \
     sgender enum('男', '女') DEFAULT '男' \
   )ENGINE=MyISAM CHARSET=utf8"
);

4)删除表

query.exec("drop table student");

5)添加

// 添加单条数据
query.exec("insert into student values(1, '关羽', 30, '男')");
query.exec("insert into student values(null, '张飞', 28, '男')");

// 批量添加 --- 方式1 
// ? 叫做占位符
query.prepare("insert into student(sname, sage, sgender) values(?,?,?)");

QVariantList nameList;
nameList << "aaa" << "bbb" << "ccc";
QVariantList ageList;
ageList << 20 << 30 << 40;
QVariantList genderList;
genderList << "男" << "女" << "男";

query.addBindValue(nameList);
query.addBindValue(ageList);
query.addBindValue(genderList);

query.execBatch();


// 批量添加 - 方式2
// :xxx : 数据名称
query.prepare("insert into student(sname, sage, sgender) values(:name, :age, :gender)");

QVariantList nameList;
nameList << "小王" << "小张" << "小赵";
QVariantList ageList;
ageList << 20 << 30 << 40;
QVariantList genderList;
genderList << "男" << "女" << "男";

query.bindValue(":name", nameList);
query.bindValue(":age", ageList);
query.bindValue(":gender", genderList);

query.execBatch();

6)查询

// 执行查询
query.exec("select * from student");

// 判断查询结果中是否有下一条数据
while (query.next()) {
  // value 方法用来设置列数据项,结果可以继续转为具体的数据类型
  qDebug() 
    << query.value(0).toInt()
    << query.value(1).toString()
    << query.value("sage").toInt()
    << query.value("sgender").toString();
}

7)更新

query.exec("update student set sage=35 where sno=1");

// 注意事项: 字符串字段需要加引号
QString sql = QString("update student set sname='%1',sage=%2,sgender='%3' where sno=%4").arg("孙尚香").arg(20).arg("女").arg(1);
query.exec(sql);

8)删除

query.exec("delete from student where sno=2");

// 批量删除
QString sql = QString("delete from student where sno in (%1)").arg("1,2,3");
query.exec(sql);

9)关闭数据库

db.close();

5. 可视化操作

  • Qt 提供了3个类来访问数据库,并且能够使用图形化方式来显示和操作数据

  • QSqlTableModel : 创建一个可编辑的表格式数据模型(注意:只能应用于单表)

  • QTableView :常见一个表格视图,可以将 QSqlTableModel 创建的模型自动填充到表格中

  • QSqlRelationalTableModel :创建关联数据类型的数据模型

5.1 准备工作

1.使用可视化操作时,也需要先进行数据库链接

// 链接数据库服务器
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setPort(3306);
db.setUserName("root");
db.setPassword("root");
db.setDatabaseName("study");

if (!db.open())
{
  qDebug() << db.lastError().text();
}

2.设置ui界面

5.2 显示表格(R)

目标:查询 student 表中数据,并显示在表格中

实现步骤:

  1. 使用模型关联数据表

  2. 查询数据

  3. 关联模型和视图

// 实例化 Student 表模型
stuModel = new QSqlTableModel(this);


// 1. 查询所有数据
// 设置stuModel模型关联的数据表
stuModel->setTable("student");
// 查询表中所有数据
stuModel->select();
// 将数据显示在视图中
ui->stuTableView->setModel(stuModel);

设置表头

// 设置表头
stuModel->setHeaderData(0, Qt::Horizontal, "学号");
stuModel->setHeaderData(1, Qt::Horizontal, "姓名");
stuModel->setHeaderData(2, Qt::Horizontal, "昵称");
stuModel->setHeaderData(3, Qt::Horizontal, "性别");
stuModel->setHeaderData(4, Qt::Horizontal, "年龄");
stuModel->setHeaderData(5, Qt::Horizontal, "入学时间");
stuModel->setHeaderData(6, Qt::Horizontal, "所属学院");

 设置表格修改方式为手动提交

// 设置表格隔行变色
ui->tableView->setAlternatingRowColors(true);

// 设置表格宽度
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 设置单元格修改方式
stuModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

5.3 添加

实现添加需要两步:

  1. 创建新行 QSqlRecord

  2. 点击 "提交" 按钮时将新数据提交到数据库

void Widget::on_addBtn_clicked()
{
    // 创建新数据记录
    QSqlRecord record = stuModel->record();
    // 获取数据行数
    int rowNum = stuModel->rowCount();
    // 添加一条新的空数据
    stuModel->insertRecord(rowNum, record);
}
void Widget::on_pushButton_4_clicked()
{
    stuModel->submitAll();
}

submitAll 方法:提交所有,包含本次添加,也可以包含同时修改的别的数据

5.4 删除

  • 实现思路:点击删除时,获取所有选中的行的行号,根据行号来执行删除

  • QItemSelectionModel: 能够获取所有选中的行(对象)

  • QModelIndexList : 能够从选中的行对象中 获取 对应的索引号

  • 有了索引号之后,就能循环从 stuModel 中进行删除

// 获取所有的选中行
QItemSelectionModel *selectedModel = ui->tableView->selectionModel();


// 获取选中行的行号
QModelIndexList indexList = selectedModel->selectedRows();

for (int i = 0; i < indexList.size(); i++)
{
  qDebug() << i << indexList[i].row();
  stuModel->removeRow(indexList[i].row());
}

5.5 撤销

void Widget::on_cancelModifyBtn_clicked()
{
    stuModel->revertAll();
    stuModel->submitAll();
}

5.6 排列

方案一: 使用 tableView 进行排列

方案二: 使用 stuModel 进行排列

// 降序排列
void Widget::on_descBtn_clicked()
{
//    ui->stuTableView->sortByColumn(0, Qt::DescendingOrder);
    stuModel->sort(0, Qt::DescendingOrder);
}
// 升序排列
void Widget::on_ascBtn_clicked()
{
//    ui->stuTableView->sortByColumn(0, Qt::AscendingOrder);
    stuModel->sort(0, Qt::AscendingOrder);
}

5.7 搜索

核心方法:setFilter(搜索条件)

实现思路:

  1. 点击搜索按钮时,获取关键词

  2. 拼接模糊查找的条件,调用 setFilter 进行设置

  3. 重新调用 select 方法执行查询,就能将满足条件的数据显示在表格中

// 搜索
void Widget::on_searchBtn_clicked()
{
    // 获取搜索关键词
    QString str = ui->lineEdit->text();
    // 构建模糊查询
    QString filterStr = QString("sname like '%%1%'").arg(str);
    // 过滤
    stuModel->setFilter(filterStr);
    // 查询
    stuModel->select();
}

5.8 关联表设置

QSqlTableModel: 适合单表操作

QSqlRelationalTableModel: 适合多表关联操作

stuModel = new QSqlRelationalTableModel(this);
stuModel->setTable("student");

// 设置 student 与 dept 的关联关系
stuModel->setRelation(6, QSqlRelation("dept", "dno", "dname"));
stuModel->select();

// 设置学科列的可选项只能是 dept 表中的数据
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

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

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

相关文章

【源码+文档+调试讲解】基于安卓的小餐桌管理系统springboot框架

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低运营人员成本&#xff0c;实现了小餐桌的标准化、制度化、程序化的管理&#xff0c;有效地防止了小餐桌的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、准确地查询和修…

vue+ElementUI—实现基础后台管理布局(sideBar+header+appMain)(附源码)

后台管理的模板很多&#xff0c;vue本身就提供了完整的vue-template-admin&#xff0c;vue-admin-beautiful等后台管理系统化框架&#xff0c;但是这些框架正是因为成体系而显得繁重。假如你想搭建一个静态的后台管理模板页面和几个单独的菜单页面&#xff0c;直接就上框架是否…

学习 PostgreSQL + Spring Boot 3 +mybatisplus整合过程中的报错记录

今天计划学习 PostgreSQL&#xff0c;并顺便尝试使用 Spring Boot 3.x 框架&#xff0c;打算整合 Spring Boot 3、PostgreSQL 和 MyBatis-Plus。整合后一直出现以下报错&#xff1a; 去AI上面搜了讲的是sqlSessionFactory 或 sqlSessionTemplate 没有正确配置 初始分析&#…

MySQL-01.课程介绍

一.什么是数据库 二.数据库产品 三.课程安排

Python_函数式编程核心(高阶函数、闭包等)

函数式编程(functional programming)其实是个很古老的概念&#xff0c;诞生距今快60年啦&#xff01;最古老的函数式编程语言Lisp新出现的函数式编程语言&#xff1a;比如Erlang、Scala、clojure等热门语言&#xff1a;Python、java、JavaScript、C等都增加了函数式编程的一些特…

SpringBoot购物推荐网站开发:架构设计与技术实现

3系统分析 3.1可行性分析 通过对本东大每日推购物推荐网站实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本东大每日推购物推荐网站采用JAVA作为开发语言&…

SpringBoot框架下购物推荐系统的架构与实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

VSCode搭建C/C++开发环境【Windows】

VSCode搭建C/C开发环境 1. 配置C/C开发环境1.1 下载和配置MinGW-w64编译器套件1.2 安装C/C插件 2. 在VSCode上编写C语言代码&#xff0c;并编译执行2.1 先打开一个文件夹&#xff0c;写一份C语言代码2.2 设置C/C编译的选项&#xff1a;c_cpp_properties.json2.3 创建执行任务&a…

CDGA|数据治理:唤醒“沉睡”的数据,激发无限价值潜能

在当今这个信息爆炸的时代&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;许多企业面临着数据孤岛、数据质量低下、数据利用率不高等问题&#xff0c;导致大量“沉睡”的数据未能发挥其应有的价值。数据治理&#xff0c;作为解锁这些数据宝藏的钥匙&#xff0c;…

连夜爆肝收藏各大云服务新老用户优惠活动入口地址(内含免费试用1个月的地址),适用于小白,大学生,开发者,小企业老板....

具体请前往&#xff1a;云服务器优惠活动入口大全--收藏各主流云厂商的云服务器等系列产品的优惠活动入口&#xff0c;免费试用1个月活动入口&#xff0c;让新老用户都能根据使用场景和身份快速锁定优惠权益 经济下滑&#xff0c;被优化增多&#xff0c;大学生就业难&#xff0…

Linux之如何找回 root 密码?

1、启动系统&#xff0c;进入开界面&#xff0c;在界面中按“e"进入编辑界面 2、进入编辑界面&#xff0c;使用键盘上的上下键把光标往下移动&#xff0c;找到以”Linux16“开通内容所在的行数&#xff0c;在行的最后面输入&#xff1a;init/bin/sh 3、输入完成后&…

Windows,MySQL主从复制搭建

前提&#xff1a;windows环境&#xff0c;同一个服务器安装多个相同版本的mysql数据库 多个MySQL服务搭建完成后&#xff0c;下面我们进行主从复制的相关配置 1.主数据库 执行指令 #创建用户 CREATE USER slavelocalhost IDENTIFIED BY 123456;#授权 GRANT REPLICATION SLA…

plpo vue实战版教程

vue实战版教程 什么是plpo安装1.将plop添加到您的项目2.全局安装plop(可选&#xff0c;但建议使用方便)3.在项目根目录下创建一个 plopfile.js vue 实战&#xff08;后台管理系统 - 增删改查&#xff09;所需文件文件介绍创建配置文件 plopfile.js创建模板和脚本命令文件模板创…

Emu3:北京智源推出AI多模态世界模型,超越DeepMind和微软,刷新了8项性能指标

Emu3是北京智源人工智能研究院推出的一款原生多模态世界模型&#xff0c;采用智源自研的多模态自回归技术路径&#xff0c;在图像、视频、文字上联合训练&#xff0c;使模型具备原生多模态能力&#xff0c;实现图像、视频、文字的统一输入和输出。Emu3将各种内容转换为离散符号…

食堂校园预约就餐系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;论坛管理&#xff0c;用户管理&#xff0c;商家管理&#xff0c;公告信息管理&#xff0c;基础数据管理 微信端账号功能包括&#xff1a;系统首页&#xf…

【Flutter、H5、Web?前端个人总结】分享从业经历经验、自我规范准则,纯干货

前言 hi&#xff0c;正式接触web前端已经经过了两年的时间&#xff0c;从大学的java后端转型到web前端&#xff0c;再到后续转战Flutter&#xff0c;逐渐对前端有了一些心得体会&#xff0c;其实在当下前端的呈现形式一直在变化&#xff0c;无论你是用原生、还是web还是混编的…

vulnhub-Kioptrix_Level_1靶机的测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、解决检测不到IP的问题 2、信息搜集 3、利用exp ①mod_ssl2.8版本漏洞 ②smb2.2版本漏洞 四、结论 一、测试环境 1、系统环境 渗透机&#xff1a;kali2021.1(192.168.202.134) 靶 机…

【前端构建】Webpack: 现代前端开发的核心工具

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Webpack: 现代前端开发的核心工具1. 引言2. Webpack 的核心概念2.1 入口&#x…

vmware下ubuntu18.04中使用笔记本的摄像头

步骤1&#xff1a;在windows中检查相机状态 win10系统中&#xff0c;在左下的搜索栏&#xff0c;搜索“相机”&#xff0c;点击进入即可打开相机&#xff0c;并正常显示图像。 注意&#xff1a;如果相机连接到了虚拟机&#xff0c;则不能显示正常。 步骤2&#xff1a;…

解决ubuntu 下 VS code 无法打开点击没反应问题

从Ubuntu 22.04 升级到ubuntu 24.04 后&#xff0c;发现Vsode无法打开&#xff0c;不论是点击图标&#xff0c;还是terminator里面运行code 可执行程序&#xff0c;均没有反应。debug如下: 提示权限不够。 解决方案&#xff1a; sudo sysctl -w kernel.apparmor_restrict_unp…