QT_数据库

查看QT支持的数据库类型

主要代码:

QStringList sl = QSqlDatabase::drivers();
foreach(QString str, sl)
{qDebug() << str;
}

程序输出:

"QSQLITE"
"QODBC"
"QODBC3"
"QPSQL"
"QPSQL7"

如果想使用其他数据库,需要自己手动添加

数据库操作
加载数据库

主要代码:

{//加载数据库,addDatabase第一个参数为数据库驱动名,第二个为连接名QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "connect-name");//设置数据库名字db.setDatabaseName("Live");if(db.open()){//successdb.close();}
}
QSqlDatabase::removeDatabase("connect-name");

注意:

使用驱动程序类型和连接名称ConnectionName将数据库添加到数据库连接列表中。如果已经存在名为ConnectionName的数据库连接,则删除该连接。

数据库连接使用连接名来定义,而不是使用数据库名,可以向相同的数据库创建多个连接。
QSqlDatabase也支持默认连接的概念,默认连接就是一个没有命名的连接。

通过连接寻找数据库

主要代码:

QSqlDatabase db = QSqlDatabase:: database("connect-name");

注意:

  1. 数据库的连接是不能跨线程使用的,在主线程中加载数据库得到的连接名,只能在主线程中使用,而不能在子线程中使用。
  2. 如果想让数据库在子线程中使用,则必须在子线程中加载数据库,得到新的连接名,然后在子线程中使用这个新的连接找到数据库,然后对其操作。
执行SQL语句

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

QSqlDatabase db = QSqlDatabase::database("connection-name");
QSqlQuery query(db);
query.exec("sql语句");

创建表

create table if not exists 表名(字段1,字段2,...)

新增数据

insert into 表名 values(数据1,数据2,...)

查询数据

select * from 表名

删除数据

delete from 表名 where 条件控制语句

更新数据

update 表名 set 字段1=数据1,字段2=数据2...
事务操作

事务可以保证一个复杂的操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,是不可分割的工作单位。
相关函数:

QSqlDriver::hasFeature(QSqlDriver::Transactions)
QSqlDatabase::transaction()
QSqlDatabase::commit()
QSqlDatabase::rollback()

事务操作实际上是将一系列操作后的结果进行缓存,在最后进行commit的时候,再一次性同步到数据库中,如果中间有操作失败,则调用rollback进行回滚,撤销缓存中的操作结果。

SQL模型类

Qt提供了3个更高层的类来访问数据库,分别是QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。
这3个类都是从QAbstractTableModel派生来的,可以很容易地实现将数据库中的数据在QListView和QTableView等视图类中进行显示。

QSqlQueryModel模型

主要代码

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite-connect");
db.setDatabaseName("data");
if(db.open())
{//successQSqlQuery query(db);query.exec("create table if not exists User(username,password,phoneNumber)");
}
QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select * from User",db);
ui->tableView->setModel(model);

QSqlQueryModel模型默认是只读的,所以我们在窗口上并不能对表格中的内容进行修改。但是我们可以创建自己的模型,然后按照我们自己的需要来显示数据和修改数据。如果要想使其可读写,需要自己的类继承自QSqlQueryModel,并且重写setData()和flags()两个函数,如果我们要改变数据的显示,就要重写data()函数。

QSqlTableModel模型

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

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "sqlite-connect");
db.setDatabaseName("data");
if(db.open())
{//successQSqlQuery query(db);query.exec("create table if not exists User(username,password,phoneNumber)");
}
QSqlTableModel *model = new QSqlTableModel(this,db);
model->setTable("User");
model->select();
model->setEditStrategy(QSqlTableModel::OnFieldChange);
ui->tableView->setModel(model);

QSqlTableModel::EditStrategy

Constant                        Value   Description
QSqlTableModel::OnFieldChange   0       tableView中数据一更改就同步到数据库中
QSqlTableModel::OnRowChange     1       修改一行,当点击另一行时,将修改的哪一行同步到数据库中
QSqlTableModel::OnManualSubmit  2       自己手动操作,submitAll() or revertAll()
QSqlRelationalTableModel模型

QSqlRelationalTableModel继承于QSqlTableModel
QSqlRelationalTableModel类为单个数据库表提供可编辑的数据模型,并具有外键支持。
QSqlRelationalTableModel类似于QSqlTableModel,但允许将列设置为其他数据库表的外键。

外键(foreign key): 如果一个A表的字段指向另一个B表的主键,则此字段就为A表的外键。用于表示表外之间的关系。存在外键的表,称之为从表(子表),外键指向的表,称之为主表(父表)。

这两张表都必须要有主键

主键(primary key):每个表只能有最多一个主键,具有主键的表中的每一行在其主键列中必须具有唯一的值组合。

QSqlRelationalTableModel设置外键关联表:

//设置当前表的关联表
void QSqlRelationalTableModel::setRelation(int column,const QSqlRelation &relation);QSqlReltion::QSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn)------------------------------------------------
tableModel->setRelation(外键的列号, QSqlRelation(关联_表名, 关联外键_字段名, 替换_字段(关联表)));

Qt中还提供了一个QSqlRelationalDelegate委托类,这个委托为一个外键提供了一个QComboBox部件来显示所有可选的数据。

ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

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

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

相关文章

提问cpp之编译单元

提问cpp之编译单元 提问1&#xff1a;回答1&#xff1a;为什么模板都写在头文件里&#xff0c;写在.cpp文件会怎样&#xff1f;头文件中直接定义int a会有什么问题&#xff1f;为什么重复定义会出问题&#xff0c;这是谁判断的&#xff1f; 提问2&#xff1a;回答2&#xff1a;…

featup入坑笔记

一、新建环境 在conda中建立一个虚拟环境featup&#xff0c; conda create -n featup python3.9 二、开始配置&#xff1a; 我是先下载了FeatUp&#xff0c;之后 pip install -e . -i https://mirrors.aliyun.com/pypi/simple/ 但是&#xff0c;突然出错了&#xff0c;说无法…

leetcode2529-正整数和负整数的最大计数

题目: 给你一个按 非递减顺序 排列的数组 nums &#xff0c;返回正整数数目和负整数数目中的最大值。 换句话讲&#xff0c;如果 nums 中正整数的数目是 pos &#xff0c;而负整数的数目是 neg &#xff0c;返回 pos 和 neg二者中的最大值。 注意&#xff1a;0 既不是正整数…

MyBatis输出映射

1 resultType resultType: 执行 sql 得到 ResultSet 转换的类型&#xff0c;使用类型的完全限定名或别名。如果返回的是集合&#xff0c;设置的是集合元素的类型&#xff0c;而不是集合本身。resultType 和 resultMap&#xff0c;不能同时使用。 1.1 输出简单类型 案例&…

记Kubernetes(k8s):访问 Prometheus UI界面:Warning: Error fetching server time

记Kubernetes&#xff08;k8s&#xff09;&#xff1a;访问 Prometheus UI界面:Warning: Error fetching server time 1、报错详情2、解决3、再次访问 PrometheusUI界面 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、报错详情 Warning:…

软件杯 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的人体跌倒检测算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满…

MyBatis事务管理

MyBatis的事务管理是由TransactionFactory和Transaction两个接口定义的&#xff0c;TransactionFactory负责生成Transaction&#xff0c;这是一个典型的工厂模式。 官方提供了事务管理的两种模式&#xff1a; Managed&#xff1a;对应ManagedTransactionFactory和ManagedTran…

第四百四十一回 再谈flutter_native_splash包

文章目录 1. 知识回顾2. 使用方法3. 示例代码4. 经验与总结4.1 经验分享4.2 内容总结 我们在上一章回中介绍了"overlay_tooltip简介"相关的内容&#xff0c;本章回中将 再谈flutter_native_splash包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我…

视频插针调研

视频插针 1、评估指标2、准确度3、实时4、视频流处理3、实时RIFE视频插帧测试 1、评估指标 参考&#xff1a;https://blog.csdn.net/weixin_43478836/article/details/104159648 https://blog.csdn.net/weixin_43605641/article/details/118088814 PSNR和SSIM PSNR数值越大表…

面试准备 集合 List

ArrayList 底层实现 使用Object[] 动态数组进行存储 特性 支持存储null值非线程安全支持快速访问 初始化方法 无参–返回一个空的列表&#xff08;DEFAULTCAPACITY_EMPTY_ELEMENTDATA&#xff09;指定初始容量&#xff1a; new ArrayList(20);指定集合 new ArrayList(col…

Opencv驱动摄像头

Opencv驱动摄像头&#xff0c;此段代码只能驱动电脑自带摄像头&#xff0c;目前没有分析出为何不能驱动另外连接的相机&#xff01; #include<iostream> #include<opencv2\core.hpp> #include<opencv2\highgui.hpp> #include<opencv2\imgproc.hpp> #i…

ubuntu下NTFS分区无法访问挂载-解决办法!

Ubuntu系统下&#xff0c;有的时候发现&#xff0c;挂载的NTFS文件系统硬盘无法访问。点击弹出类似问题&#xff1a; Error mounting /dev/sda1 at /media/root/新加卷: Command-line mount -t "ntfs" -o "uhelperudisks2,nodev,nosuid,uid0,gid0" "/…

Linux下的C语言文件编程

概念引入 window &#xff0c;linux如何修改一个文件&#xff0c;比如写一个word文档&#xff1a; 打开/创建文件 -->编辑文件 -->保存文件 -->关闭文件 我们需要使用代码自动化完成以上操作: 操作系统(linux)给我们提供了一系列的API: 打开&#xff1a; open 读写:…

【攻防世界】mfw(.git文件泄露)

首先进入题目环境&#xff0c;检查页面、页面源代码、以及URL&#xff1a; 发现页面无异常。 使用 dirsearch 扫描网站&#xff0c;检查是否存在可访问的文件或者文件泄露&#xff1a; 发现 可访问界面/templates/ 以及 .git文件泄露&#xff0c;故使用 GItHack 来查看泄露的 …

C语言奇技淫巧之--用宏定义替换函数名的另外一种思路

时间有限&#xff0c;简要记录原理。 快速回忆要点&#xff1a; #if definde(FEATURE_A) #define myfunc _myfunc #endif int myfunc(int a, int b) 场景&#xff1a; 假设某个功能函数针对不同的makefile配置需要有不同的函数名字&#xff0c;通常做法如下&#xff1a; #if …

传统方法(OpenCV)_车道线识别

一、思路 基于OpenCV的库&#xff1a;对视频中的车道线进行识别 1、视频处理&#xff1a;视频读取 2、图像转换&#xff1a;图像转换为灰度图 3、噪声去除&#xff1a;高斯模糊对图像进行去噪&#xff0c;提高边缘检测的准确性 4、边缘检测&#xff1a;Canny算法进行边缘检测…

状态模式(行为型)

目录 一、前言 二、状态模式 三、总结 一、前言 状态模式(State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类&#xff0c;但实际上&#xff0c;由于状态模式的引入&#xff0c;行为的变…

Python单元测试pytest捕获日志输出

使用pytest进行单元测试时&#xff0c;遇到了需要测试日志输出的情况&#xff0c;查看了文档 https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html https://docs.pytest.org/en/latest/how-to/logging.html 然后试了一下&#xff0c;捕捉logger.info可以用…

CentOS 7.9 额外安装一个Python3.x版本详细教程

Centos7默认的python版本是2.7&#xff0c;根据需要我们额外安装一个Python3.x版本。 1、安装基础环境 yum update -yyum -y groupinstall "Development tools"yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc …

ArchiveBo

目录 1、 ArchiveBo 2、 BackResponseBo 3、 RelationshipVoKey 3.1、 * 内容主键 3.2、 * 项目主键