Qt入门------数据库操作

article/2025/11/3 2:27:59

文章目录

  • 一、数据库
    • 1.数据库驱动
    • 2.查询驱动
    • 3.连接数据库
    • 4.执行sql语句
    • 5.插入数据
    • 6.事务
  • 二 ,sql模型类
    • 1.QSqlQueryModel模型
    • 2.QSqlTableModel模型
    • 3.QSqlRelationalTableModel模型


一、数据库

Qt中的Qt SQL模块提供了对数据库的支持,模块中类可分为三层:驱动层,sql接口层,用户层。
驱动层:(QSqlDriver,QSqlDriverCreator,QSqlDriverCreatorBase,QSqlDriverPlugin)为具体的数据库和SQL接口层之间提供了底层的桥梁;
SQL接口层:(QSqlDatabase,QSqlQuery,QSqlError,QSqlRecord)提供了对数据库的访问,其中QSqlDatabase类用来创建连接,QSqlQuery类可以使用SQL语句来实现与数据库交互;
用户接口层:(QSqlTableModel,QSqlQueryModel,QSqlRelationalTableModel)实现了将数据库中的数据链接到窗口部件上,这些类是使用模型/视图框架实现的,它们是更高层次的抽象;

1.数据库驱动

Qt SQL模块使用数据库驱动插件来和不同的数据库接口进行通信。由于Qt SQL模块的接口是独立于数据库的,所以所有数据库特定的代码都包含在了这些驱动中。Qt默认支持一些驱动:

驱动名称数据库
QSQLITE2SQLite2版本
QSQLITESQLite3版本
QMYSQLMySQL
QODBCSQL Service
QPSQLPostgreSQL(>=7.3版本)

2.查询驱动

#include <QApplication>
#include <QSqlDatabase>
#include <QDebug>
#include <QStringList>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QStringList drivers = QSqlDatabase::drivers();foreach(QString driver, drivers)qDebug() << driver;return a.exec();
}

在.pro文件中加入sql模块
在这里插入图片描述

3.连接数据库

数据库连接使用连接名来定义,而不是使用数据库名,可以向相同的数据库创建多个连接。QSqlDatabase也支持默认连接的概念,默认连接就是一个没有命名的连接。在使用QSqlQuery或者QSqlQueryModel的成员函数时需要指定一个连接名作为参数,如果没有指定,那么就会使用默认连接。

原型:QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const
QString &connectionName = QLatin1String( defaultConnection ))

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("book");
db.setUserName("root");
db.setPassword("123456");
if(!db.open())
{qDebug() << "fail to connect mysql" << db.lastError().text();
}

创建两个名为“first”和“second”的连接:

QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL", "first");
QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL", "second");

创建完连接后,可以在任何地方使用QSqlDatabase::database()静态函数通过连接名称获取指向数据库连接的指针,如果调用该函数时没有指明连接名称,那么会返回默认连接,例如:

QSqlDatabase defaultDB = QSqlDatabase::database();
QSqlDatabase firstDB = QSqlDatabase::database("first");
QSqlDatabase secondDB = QSqlDatabase::database("second");

要移除一个数据库连接,需要先使用QSqlDatabase::close()关闭数据库,然后使用静态函数QSqlDatabase::removeDatabase()移除该连接。
连接SQL Server数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(QString("DRIVER={SQL SERVER}SERVER=%1;DATABASE=%2;UID=%3;PWD=%4;").arg("IP").arg("dbname").arg("user").arg("password"));
bool ok =db.open();

连接SQLite数据库

QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");
db1.setHostName("IP");
db1.setDatabaseName("dbname");
db1.setUserName("user");
db1.setPassword("password");

4.执行sql语句

QSqlQuery类提供了一个接口,用于执行SQL语句和浏览查询的结果集。要执行一个SQL语句,只需要简单的创建一个QSqlQuery对象,然后调用QSqlQuery::exec()函数即可。

QSqlQuery query;
query.exec("select * from student");

QSqlQuery提供了对结果集的访问,可以一次访问一条记录。当执行完exec()函数后,QSqlQuery的内部指针会位于第一条记录前面的位置。必须调用一次QSqlQuery::next()函数来使其前进到第一条记录,然后可以重复使用next()函数来访问其他的记录,直到该函数的返回值为false,

while(query.next())
{  qDebug() << query.value(0).toInt() << query.value(1).toString();  
}

在QSqlQuery类中提供了多个函数来实现在结果集中进行定位,比如next()定位到下一条记录,previous()定位到前一条记录,first()定位的第一条记录,last()定位到最后一条记录,seek(n)定位到第n条记录。当前行的索引可以使用at()返回;record()函数可以返回当前指向的记录。

5.插入数据

插入一条记录

query.exec("insert into student (id, name) values (1, 'LI')");

同一时间插入多条记录,可以使用占位符来完成。Qt支持两种占位符:名称绑定和位置绑定。
1名称绑定

query.prepare("insert into student (id, name) values (:id, :name)");
int idValue = 1;
QString nameValue = "Li";
query.bindValue(":id", idValue);
query.bindValue(":name", nameValue);
query.exec();

2位置绑定

query.prepare("insert into student (id, name) values (?, ?)");
int idValue = 1;
QString nameValue = "Li";
query.addBindValue(idValue);
query.addBindValue(nameValue);
query.exec();

当要插入多条记录时,只需要调用QSqlQuery::prepare()一次,然后使用多次bindValue()或者addBindValue()函数来绑定需要的数据,最后调用一次exec()函数就可以了。其实,进行多条数据插入时,还可以使用批处理进行:

query.prepare("insert into student (id, name) values (?, ?)");
QVariantList ids;
ids << 1 << 2 << 3;
query.addBindValue(ids);
QVariantList names;
names << "Li" << "Wang" << "Liu";
query.addBindValue(names);
if(!query.execBatch()) 
qDebug() << query.lastError();

6.事务

事务可以保证一个复杂的操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,是不可分割的工作单位。如果底层的数据库引擎支持事务,QSqlDriver::hasFeature(QSqlDriver::Transactions)会返回true。可以使用QSqlDatabase::transaction()来启动一个事务,然后编写希望在事务中执行的SQL语句,最后调用QSqlDatabase::commit()提交或者QSqlDatabase::rollback()回滚。使用事务必须在创建查询以前就开始事务

QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM student WHERE name = 'Li'");
if (query.next())
{int id = query.value(0).toInt();query.exec("INSERT INTO project (id, name, ownerid) ""VALUES (201, 'MProject', "+ QString::number(id) + ')');
}
QSqlDatabase::database().commit();

二 ,sql模型类

Qt还提供了3个更高层的类来访问数据库,分别是QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。
这3个类都是从QAbstractTableModel派生来的,可以很容易地实现将数据库中的数据在QListView和QTableView等项视图类中进行显示。使用这些类的另一个好处是,这样可以使编写的代码很容易的适应其他的数据源。例如,如果开始使用了QSqlTableModel,而后来要改为使用XML文件来存储数据,这样需要做的仅是更换一个数据模型

1.QSqlQueryModel模型

QSqlQueryModel提供了一个基于SQL查询的只读模型。

QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select * from student");
model->setHeaderData(0, Qt::Horizontal, tr("学号"));
model->setHeaderData(1, Qt::Horizontal, tr("姓名"));
model->setHeaderData(2, Qt::Horizontal, tr("课程"));
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

在这里插入图片描述

先创建了QSqlQueryModel对象,然后使用setQuery()来执行SQL语句查询整张student表,并使用setHeaderData()来设置显示的标头。后面创建了视图,并将QSqlQueryModel对象作为其要显示的模型。这里要注意,其实QSqlQueryModel中存储的是执行完setQuery()函数后的结果集,所以视图中显示的是结果集的内容。QSqlQueryModel中还提供了columnCount()返回一条记录中字段的个数;rowCount()返回结果集中记录的条数;record()返回第n条记录;index()返回指定记录的指定字段的索引;clear()可以清空模型中的结果集。

2.QSqlTableModel模型

QSqlTableModel提供了一个一次只能操作一个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。
创建数据表

QSqlQuery query;
// 创建student表
query.exec("create table student (id int primary key, ""name varchar, course int)");
query.exec("insert into student values(1, '李', 10)");
query.exec("insert into student values(2, '马', 11)");
query.exec("insert into student values(3, '孙', 12)");
// 创建course表
query.exec("create table course (id int primary key, ""name varchar, teacher varchar)");
query.exec("insert into course values(10, '数学', '王老师')");
query.exec("insert into course values(11, '英语', '张老师')");
query.exec("insert into course values(12, '计算机', '李老师')");

显示表:

QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("student");
model->select();
// 设置编辑策略
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

在这里插入图片描述

创建一个QSqlTableModel后,只需使用setTable()来为其指定数据库表,然后使用select()函数进行查询,调用这两个函数就等价于执行了“select * from student”语句。这里还可以使用setFilter()来指定查询时的条件。在使用该模型以前,一般还要设置其编辑策略,它由QSqlTableModel::EditStrategy枚举类型定义。

常量描述
QSqlTableModel::OnFieldChange所有对模型的改变都会立即应用到数据库
QSqlTableModel::OnRowChange对一条记录的改变会在用户选择另一条记录时被应用
QSqlTableModel::OnManualSubmit所有的改变都会在模型中进行缓存,直到调用submitAll()或者reverAll()函数

修改

// 开始事务操作model->database().transaction();if (model->submitAll()){if(model->database().commit()) // 提交QMessageBox::information(this, tr("tableModel"),tr("数据修改成功!"));} else{model->database().rollback(); // 回滚QMessageBox::warning(this, tr("tableModel"),tr("数据库错误: %1").arg(model->lastError().text()),QMessageBox::Ok);}

撤销修

model->revertAll();

查询

//全部数据
model->setTable("student");
model->select();
//进行筛选
QString name = "xxx" ;
// 根据姓名进行筛选,一定要使用单引号
model->setFilter(QString("name = '%1'").arg(name));
model->select();

升序

//id字段,即第0列,升序排列
model->setSort(0, Qt::AscendingOrder);
model->select();

删除

    // 获取选中的行int curRow = ui->tableView->currentIndex().row();// 删除该行model->removeRow(curRow);int ok1 = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定删除当前行吗?"), QMessageBox::Yes, QMessageBox::No);if(ok == QMessageBox::No){ // 如果不删除,则撤销model->revertAll();} else { // 否则提交,在数据库中删除该行model->submitAll();}

3.QSqlRelationalTableModel模型

QSqlRelationalTableModel继承自QSqlTableModel,并且对其进行了扩展,提供了对外键的支持。一个外键就是一个表中的一个字段和其他表中的主键字段之间的一对一的映射。例如,student表中的course字段对应的是course表中的id字段,那么就称字段course是一个外键。因为这里的course字段的值是一些数字,这样的显示很不友好,使用关系表格模型,就可以将它显示为course表中的name字段的值。

QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this);
model->setTable("student");
model->setRelation(2, QSqlRelation("course", "id", "name"));
model->select();
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

在这里插入图片描述
Qt中还提供了一个QSqlRelationalDelegate委托类,它可以为QSqlRelationalTableModel显示和编辑数据。这个委托为一个外键提供了一个QComboBox部件来显示所有可选的数据,这样就显得更加清晰了。
view->setItemDelegate(new QSqlRelationalDelegate(view));
在这里插入图片描述


http://chatgpt.dhexx.cn/article/7qjQvh8n.shtml

相关文章

Java的数据库操作

Java的数据库操作&#xff0c;上学期末的课设是用到的&#xff0c;然而老师把JDBC连接mysql数据库的代码和配置文件已经给好了&#xff0c;那时对它可以说是只有一点点印象。 今天跟着书走一边敲一边&#xff0c;总算是有所进步。 数据库表的创建和初始数据的操作&#xff0c…

一文详解python中的数据库操作

python中的数据库操作 一、数据库编程接口1. 连接对象 二、使用内置的SQLite1.创建数据库文件2.操作SQLite 三、MySql数据库的使用3.1 安装MySql3.2 设置环境变量3.3 启动MySql3.4 使用navicat for mysql 管理软件3.5 安装PyMysql模块3.6 连接数据库 四、创建数据表4.1 创建boo…

数据库操作练习题

如何查看员工表中的所有字段&#xff1f; 如何查看员工表中的姓名和性别&#xff1f; 如何知道每个员工一年的总收入&#xff1f; 怎么查看女员工的信息&#xff1f; 如何查看月薪范围位于 8000 到 12000 之间的员工&#xff1f; 查询员工中叫做“张三”、“李四” 或“张飞”的…

MySQL(一)数据库操作

1.关系型数据库与非关系型数据库区别与联系 1.关系型数据库 ( SQL ) MySQL , Oracle , SQL Server , SQLite , DB2 , … 关系型数据库通过外键关联来建立表与表之间的关系 2.非关系型数据库 ( NOSQL ) Redis , MongoDB , … 非关系型数据库通常指数据以对象的形式存储在数据…

使用ORACLE 进行数据库操作

上一期讲了 如何创建表&#xff0c;例如我们创建了一个 名为 t_customer 的表&#xff0c;格式为下&#xff1a; create table t_customer(cust_id int primary key,cust_name varchar(20),cust_gender char(3),cust_age int,cust_birthday date,cust_height number(3,2),cust…

C#数据库操作

功能需求 1&#xff0c;利用随机数模拟产生每次考试成绩 2&#xff0c;将每次考试成绩存入到数据库 3&#xff0c;将每次考试成绩划分优、良、中、差、不及格五类&#xff0c;并作为查询条件&#xff0c;查询符合每种水平的成绩 技术知识点 1.random类的使用 2.数据库的链…

云数据库操作

1 云数据库创建 每一个list就相当于一个表&#xff0c;每个记录就是一条内容 云数据库存储形式是JSON2 读取云数据库值 数据库初始化 const db wx.cloud.database() 连接数据库 db.collection(需要连接的数据列表名)可以通过.doc(‘具体id号’)获取具体的信息内容获取年、月…

Android数据库操作

Android内置了一个名为SQLite的关系型数据库&#xff0c;这是一款轻量型的数据库&#xff0c;操作十分简便。SQLite与别的数据库不同的是&#xff0c;它没有数据类型。可以保存任何类型的数据到你所想要保存的任何表的任何列中。但它又支持常见的类型比如: NULL, VARCHAR, TEXT…

数据库基本操作

一、数据库基本操作 1.数据库的基本操作 -- 1.数据库的基本操作 使用test数据库 USE test; -- 查看当前test数据库中所有表 MySQL命令 SHOW TABLES; -- 查表的基本信息 SHOW CREATE TABLE student; -- -- 查看表的字段信息 desc student; 2.数据表的基本操作 -- 2.数据表的…

数据库基础操作

一、数据库的操作 数据库与客户端是通过网络进行交互的。 1、显示当前数据库 sql语句必须以 ; 结尾 show databases; 2、创建数据库 create database 数据库名; ->如果数据库sql敲错了&#xff0c;会有提示。 ->如果sql敲错了&#xff0c;可以按 ctrlc来终止sql。…

数据库的基本操作

目录 一、数据库的基本操作 1、数据库的登录及退出 2、查看所有数据库 3、显示数据库版本 4、显示时间 5、创建数据库 6、查看创建数据库的语句 7、查看当前使用的数据库 8、查看当前用户 9、使用某个数据库 10、删除数据库 二、数据表的基本操作 1、查看当前数据…

如何在IDEA上创建一个JSP项目【亲测有效】

idea上创建一个jsp项目 1、创建一个Java项目 2、创建成功后右击项目名称&#xff0c;点击Add Framework support 3、选择web application 选择适合版本&#xff0c;创建 4、创建成功后项目中会出现web文件夹 5、点击属性&#xff0c;进行配置 6、在project中配置jdk(你自己电脑…

Eclipse中安装配置Tomcat和创建JSP项目

这里写自定义目录标题 安装配置Tomcat创建JSP项目 安装配置Tomcat 下载并解压Tomcat到指定目录Eclipse菜单栏中找到Window–>Preperences->Server->Runtime Environments->Add 3.选择Tomcat文件夹 4.在Eclipse中找到Servers视图窗口&#xff0c;创建Tomcat服务…

springBoot+JSP搭建项目

1.springBoot对JSP的支持 springBoot虽然支持JSP&#xff0c;但是官方不建议使用&#xff0c;下面是官方文档解释 When running a Spring Boot application that uses an embedded servlet container (and is packaged as an executable archive), there are some limitations…

IntelliJ IDEA中创建jsp项目

创建java项目 首先需要创建一个普通的java项目 这一步很简单就不用多说了&#xff0c;按照正常操作来就行了 创建好的目录结果如下 创建Moudle 在IDEA中jsp项目是Project中的一个Moudle&#xff0c;因此我们就需要在jsp中创建一个moudle 然后Next 输入moudle名称 finishe…

IntelliJ IDEA 2021.1.2 x64版的 IDEA 创建 jsp项目

在创建jsp项目前需要 搭建JSP开发环境&#xff08;配置Tomcat服务器&#xff09;&#xff1a;https://blog.csdn.net/qq_51444577/article/details/118409179 1、 创建jsp项目 先创建一个项目 创建一个java项目 一直按next键&#xff0c;给项目取个名如 jsp03&#xff0c;按…

使用eclipse创建的第一个jsp项目

1.创建web项目 首先打开eclipse->file->new->Dymanic Web Project(如果没有这个选项&#xff0c;选other&#xff0c;打开搜索web) 点finish&#xff0c;web项目创建成功 2.创建jsp 进行第一个jsp页面的编写。右键选择目录下面的WebRoot文件夹&#xff0c;然后new…

Java EE之idea创建和运行jsp项目

1.点击打开Inteliij点击Create New Project 2.点击java,再左侧Project SDK选择安装的jdk路径&#xff0c;勾选WebApplication和Create web.xml。点击next 4.再新弹出的窗口中&#xff0c;Project name中填写项目名称这里写的是Web0903,对应的Project location也会创建一个Web…

JSP项目引入Vue.js进行项目开发(工程搭建)

Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。另一方面&#xff0…

eclipse创建第一个JSP项目

前言 ​ 本文的内容由四个部分组成&#xff0c;分别为①Tomcat的安装与配置&#xff0c;②创建第一个JSP项目&#xff0c;③打包JSP项目到Tomcat服务器上并在浏览器中运行&#xff0c;④eclipse的一些java Web的一些设置。 1、Tomcat安装与配置 ​ 到Tomcat官网下载Tomcat相…