Qt入门------数据库操作
Posted 尘客-追梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt入门------数据库操作相关的知识,希望对你有一定的参考价值。
文章目录
一、数据库
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默认支持一些驱动:
驱动名称 | 数据库 |
---|---|
QSQLITE2 | SQLite2版本 |
QSQLITE | SQLite3版本 |
Qmysql | MySQL |
QODBC | SQL Service |
QPSQL | PostgreSQL(>=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 SERVERSERVER=%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));
Qt入门系列开发教程数据类型篇QString字符串类常用操作
来了,老弟,不收藏你就后悔吧 !****点赞👍收藏⭐️留言📝 不迷路~~~
😈「作者主页 」:鱼酱2333
😈「 B站首页 」:鱼酱2333
😈「本文录入专栏」:Qt入门系列开发教程【
😈「本文内容」:基于Qt6.2.2的QString常用操作
文章目录
0.应用场景
字符串存储、字符存储。
1.QString
简介
QString字符串,Qt当中非常重要的一个类。
QString内部的方法非常多,每一个给大家都讲解一遍,那你就睡着了。遵循2/8定律,我把我工作中 最常用的API分析给大家。(过多的API会给大家造成困扰)
对于字符串操作可以分为:增、删、查、改
增
//追加字符串在字符串的末尾。
QString &append(const QString &str)
void push_back(const QString &other)
//将字符串 str 添加到该字符串的开头并返回对该字符串的引用。
QString &prepend(const QString &str)
//在给定的索引位置插入字符串 str 并返回对该字符串的引用。
QString &insert(qsizetype position, const QString &str)
//从格式字符串 cformat 和任意参数列表安全地构建格式化字符串。
static QString asprintf(const char *cformat, ...)
//返回此字符串的副本,其中编号最小的位置标记替换为字符串 a,即 %1、%2、...、%99。fieldWidth 指定参数 a 应占用的最小空间量。
//如果 a 需要的空间小于 fieldWidth,则使用字符 fillChar 将其填充到 fieldWidth。 正的 fieldWidth 会产生右对齐的文本。
//负的 fieldWidth 产生左对齐的文本。
QString arg(const QString &a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const
//数字转字符串
static QString number(int, int base=10);
static QString number(uint, int base=10);
static QString number(long, int base=10);
static QString number(ulong, int base=10);
static QString number(qlonglong, int base以上是关于Qt入门------数据库操作的主要内容,如果未能解决你的问题,请参考以下文章
Qt——Ubuntu下安装Qt Creator的方法步骤总结及其界面功能与基本设置简介(Qt简介Qt Creator版本选择软件入门常用设置)