QT 支持的数据库
QT支持市面上所有的主流数据库软件,为了区分不同公司的数据库软件,QT给不同的数据库软件定义了不同的驱动,你的电脑上安装的是哪个数据库软件,你就安装对应的驱动就可以了,下面是 QT 支持的数据库驱动名
Driver Type | Description |
---|---|
QDB2 | IBM DB2 |
QIBASE | Borland InterBase Driver |
QMYSQL | MySQL Driver |
QOCI | Oracle Call Interface Driver |
QODBC | ODBC Driver (includes Microsoft SQL Server) |
QPSQL | PostgreSQL Driver |
QSQLITE | SQLite version 3 or above |
QSQLITE2 | SQLite version 2 |
QTDS | Sybase Adaptive Server |
QSqlDatabase 数据库类
QSqlDatabase
是 Qt 的数据库管理类,用于连接和管理数据库。
Header: | #include |
---|---|
qmake: | QT += sql 记得添加数据库模块 |
核心函数
功能 | 方法 | 示例 |
---|---|---|
添加数据库 | addDatabase(driver, connName) | QSqlDatabase::addDatabase("QMYSQL"); |
设置数据库参数 | setHostName() , setDatabaseName() , setUserName() , setPassword() | db.setDatabaseName("test.db"); |
打开数据库 | open() | db.open(); |
关闭数据库 | close() | db.close(); |
获取数据库连接 | database(connName) | QSqlDatabase::database("myConnection"); |
移除数据库连接 | removeDatabase(connName) | QSqlDatabase::removeDatabase("myConnection"); |
获取数据库驱动 | drivers() | QSqlDatabase::drivers(); |
检查是否连接 | isOpen() | if(db.isOpen()) |
检查是否有表 | tables() | db.tables(); |
注意:加载sqlite3数据库,sqlite3不支持账号密码功能!所以加载时无需设置!
//数据库链接操作一般放在构造函数
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("F:/my.db");//如果数据库不存在会创建一个新的
bool ok = db.open();
QSqlRecord 表格字段信息类
//判断某个字段是否存在
bool
contains(const QString &name) const
//获取当前的字段数量
int
count() const
//获取当前字段名称
QString
fieldName(int index) const
-----------------表格头部字段获取例子----------
//获取头部字段信息
QSqlRecord sqlre = db.record(table);
for (int i=0;i<sqlre.count();i++ )
{
qDebug() << sqlre.fieldName(i);
}
重点💥:QSqlQuery SQL语句管理类
QSqlQuery
是 Qt 用于执行 SQL 语句的类,支持 增删改查(CRUD)、事务处理、绑定参数等功能。
功能 | 方法 | 示例 |
---|---|---|
构造函数 | QSqlQuery(QSqlDatabase db) | QSqlQuery(db) |
执行 SQL 语句 | exec(sql) | query.exec("SELECT * FROM users"); |
使用参数绑定 | prepare(sql) + bindValue() | query.prepare("INSERT INTO users (name) VALUES (:name)"); |
获取查询结果 | next() | query.next(); |
获取字段值 | value(index) | query.value(0).toString(); |
事务处理 | transaction() , commit() , rollback() | db.transaction(); |
✅ 示例 1:执行 SELECT
查询
QSqlQuery query;
query.exec("SELECT id, name FROM users");
while (query.next()) { // 遍历查询结果
int id = query.value(0).toInt();
QString name = query.value(1).toString();
qDebug() << "ID:" << id << ", Name:" << name;
}
✅ 示例 2:INSERT
语句
QSqlQuery query;
query.prepare("INSERT INTO users (name, age) VALUES (:name, :age)");
query.bindValue(":name", "老王");
query.bindValue(":age", 25);
if (!query.exec()) {
qDebug() << "插入失败:" << query.lastError().text();
} else {
qDebug() << "插入成功!";
}
📌 为什么要用 prepare()
+ bindValue()
?
- 防止 SQL 注入(避免
name="'; DROP TABLE users;"
这样的恶意 SQL)。 - 自动处理数据类型(例如
QString
自动转换为TEXT
)。
你可以使用 query.next()
逐行获取数据:
QSqlQuery query;
query.exec("SELECT id, name, age FROM users");
while (query.next()) {
int id = query.value("id").toInt();
QString name = query.value("name").toString();
int age = query.value("age").toInt();
qDebug() << "ID:" << id << ", Name:" << name << ", Age:" << age;
}
📌 两种方式获取字段值:
query.value(0)
通过索引获取数据。query.value("name")
通过列名获取数据。
练习:设计一个图书管理系统
需求:
- 实现书籍的增删改查
- 数据库内容显示使用
tableWidget
- 查询书籍以及修改书籍数据实现 模糊 + 条件 查询
UI 设计师界面设计
mianwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSqlDatabase>
#include <QSqlQuery>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_insertbook_bt_clicked();
void on_query_bt_clicked();
void on_del_bt_clicked();
void on_update_bt_clicked();
private:
Ui::MainWindow *ui;
QSqlDatabase base;
QString oname;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QSqlError>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//安装数据库的驱动
base = QSqlDatabase::addDatabase("QSQLITE");//sqlite3驱动
//设置数据库文件的路径名
base.setDatabaseName("F:/QT/1.db");
//打开数据库
base.open();
if (!base.open()) {
qDebug() << "数据库打开失败:" << base.lastError().text();
return;
}
//新建一个书籍表格
QSqlQuery query(base);
//执行新建表格语句
bool ret = query.exec("CREATE TABLE IF NOT EXISTS booktable ("
"name TEXT NOT NULL UNIQUE, "
"author TEXT, "
"price REAL);");
if(!ret)
{
qDebug() << "执行新建表格的语句失败了" << query.lastError().text();
return;
}
//设置表格列数
ui->tableWidget->setColumnCount(3);
//设置表格的名字
QStringList list = {"书名","作者","价格"};
ui->tableWidget->setHorizontalHeaderLabels(list);
//设置表格的行数
ui->tableWidget->setRowCount(10);
}
MainWindow::~MainWindow()
{
delete ui;
}
//添加书籍
void MainWindow::on_insertbook_bt_clicked()
{
//获取lineEdit的数据
QString Insert_book_name = ui->bname_le->text();//获取书名
QString Insert_book_author = ui->bauthor_le->text();//获取作者
QString Insert_book_price = ui->bprice_le->text();//获取价格
// 检查是否已存在
QSqlQuery checkQuery(base);
checkQuery.prepare("SELECT COUNT(*) FROM booktable WHERE name = :name");
checkQuery.bindValue(":name", Insert_book_name);
checkQuery.exec();
checkQuery.next();
if (checkQuery.value(0).toInt() > 0) {
QMessageBox::warning(this, "警告", "书籍已存在,无法重复添加!");
return;
}
//拼接字符串
QString cmd = QString("insert into booktable values('%1','%2',%3);").
arg(Insert_book_name).arg(Insert_book_author).arg(Insert_book_price);
QSqlQuery query(base);
//执行插入语句
bool ret = query.exec(cmd);
if(!ret)
{
qDebug() << "执行的插入语句失败了" << query.lastError().text();
return;
}else
{
QMessageBox::information(this, "成功", "插入书籍成功!");
}
}
//查询数据库
void MainWindow::on_query_bt_clicked()
{
QString keyword = ui->query_le->text(); // 书名/作者 关键字
QString minPrice = ui->min_price_le->text(); // 最低价格
QString maxPrice = ui->max_price_le->text(); // 最高价格
QSqlQuery query(base);
QString cmd = "SELECT * FROM booktable WHERE 1=1"; // `1=1` 方便动态拼接条件
// 添加书名/作者模糊查询(LIKE)
if (!keyword.isEmpty()) {
cmd += QString(" AND (name LIKE '%%1%' OR author LIKE '%%1%')").arg(keyword);
}
// 添加价格范围查询(BETWEEN)
if (!minPrice.isEmpty() && !maxPrice.isEmpty()) {
cmd += QString(" AND price BETWEEN %1 AND %2").arg(minPrice).arg(maxPrice);
} else if (!minPrice.isEmpty()) { // 只输入了最低价格
cmd += QString(" AND price >= %1").arg(minPrice);
} else if (!maxPrice.isEmpty()) { // 只输入了最高价格
cmd += QString(" AND price <= %1").arg(maxPrice);
}
qDebug() << "执行查询:" << cmd; // 输出 SQL 语句检查
if (!query.exec(cmd)) {
qDebug() << "查询失败:" << query.lastError().text();
return;
}
// 清空表格并重新填充数据
ui->tableWidget->clearContents();
int i = 0;
while (query.next()) {
QTableWidgetItem *item1 = new QTableWidgetItem(query.value("name").toString());
QTableWidgetItem *item2 = new QTableWidgetItem(query.value("author").toString());
QTableWidgetItem *item3 = new QTableWidgetItem(query.value("price").toString());
ui->tableWidget->setItem(i, 0, item1);
ui->tableWidget->setItem(i, 1, item2);
ui->tableWidget->setItem(i, 2, item3);
i++;
}
}
//删除数据
void MainWindow::on_del_bt_clicked()
{
//获取要删除的书籍名字
QString dname=ui->bdel_le->text();
//拼接字符串得到完整的删除语句
QString cmd=QString("delete from booktable where name='%1';").arg(dname);
QSqlQuery query(base);
//执行删除语句
bool ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"执行删除的语句失败了" << query.lastError().text();
return;
}else
{
QMessageBox::information(this, "成功", "删除书籍成功!");
}
}
//修改书籍数据
void MainWindow::on_update_bt_clicked()
{
QString cmd;
//获取原本的书名
oname=ui->oname_le->text();
//获取新的书籍信息
QString nname=ui->nname_le->text();
QString nauthor=ui->nauthor_le->text();
QString nprice=ui->nprice_le->text();
//判断字符串是否为空,为空表示这个信息你不打算修改
if(!nname.isEmpty()) //说明要修改书名
{
//拼接字符串得到完整的修改语句
cmd=QString("update booktable set name='%1' where name='%2';").arg(nname).arg(oname);
//更新原本的书名
oname=nname;
QSqlQuery query(base);
//执行修改语句
bool ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"执行修改的语句失败了" << query.lastError().text();
return;
}
}
if(!nauthor.isEmpty()) //说明要修改作者
{
//拼接字符串得到完整的修改语句
cmd=QString("update booktable set author='%1' where name='%2';").arg(nauthor).arg(oname);
QSqlQuery query(base);
//执行修改语句
bool ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"执行修改的语句失败了" << query.lastError().text();
return;
}
}
if(!nprice.isEmpty()) //说明要修改价格
{
//拼接字符串得到完整的修改语句
cmd=QString("update booktable set price=%1 where name='%2';").arg(nprice).arg(oname);
QSqlQuery query(base);
//执行修改语句
bool ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"执行修改的语句失败了" << query.lastError().text();
return;
}
}
}
效果
数据库的加密
Qt 提供了 QCryptographicHash
类来进行 MD5、SHA-1、SHA-2、SHA-3 等哈希(摘要)加密,以及 QByteArray::toBase64()
进行 Base64 编码。
使用步骤:
- 选择加密方式:使用
QCryptographicHash
(MD5、SHA-1、SHA-256、SHA-3) - 计算哈希值:
QByteArray QCryptographicHash::hash(const QByteArray &data,
QCryptographicHash::Algorithm method);
//data: 需要加密的数据
//method: 哈希方式(QCryptographicHash::Md5)
//返回值: QByteArray(二进制哈希值)
- 转换成可存储的十六进制字符串:
QByteArray::toHex();
- 存储加密后的哈希值到数据库
- 验证时比对加密后的哈希值
示例:登陆注册
#ifndef SQLLOGIN_H
#define SQLLOGIN_H
#include <QDialog>
#include <QSqlDatabase>
QT_BEGIN_NAMESPACE
namespace Ui { class SQLLogin; }
QT_END_NAMESPACE
class SQLLogin : public QDialog
{
Q_OBJECT
public:
SQLLogin(QWidget *parent = nullptr);
~SQLLogin();
private slots:
void on_pushButton_reg_clicked();
void on_pushButton_login_clicked();
void on_pushButton_exit_clicked();
private:
Ui::SQLLogin *ui;
QSqlDatabase db;
};
#endif // SQLLOGIN_H
#include "sqllogin.h"
#include "ui_sqllogin.h"
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlError>
#include <QCryptographicHash>
#include <QDebug>
SQLLogin::SQLLogin(QWidget *parent)
: QDialog(parent)
, ui(new Ui::SQLLogin)
{
ui->setupUi(this);
//添加数据库驱动
db = QSqlDatabase::addDatabase("QSQLITE");
//指定数据库文件路径
db.setDatabaseName("user.db");
//打开数据库
if(!db.open()){
QMessageBox::warning(this,"提示",QString("打开数据库文件失败:%1!").arg(db.lastError().text()));
return;
}
//建表
QString sql = QString("create table if not exists user(username text unique not NULL,password text not NULL);");
//执行sql语句
QSqlQuery query;
if(!query.exec(sql)){
QMessageBox::warning(this,"提示",QString("建表失败:%1!").arg(query.lastError().text()));
return;
}
}
SQLLogin::~SQLLogin()
{
db.close();
delete ui;
}
//注册
void SQLLogin::on_pushButton_reg_clicked()
{
QString username = ui->lineEdit_username->text();
QString password = ui->lineEdit_password->text();
//创建加密对象
QCryptographicHash hash(QCryptographicHash::Md5);
//添加要加密的数据
hash.addData(password.toUtf8());
//获取加密的结果
QByteArray arr = hash.result();
password = arr.toHex();
qDebug()<<password;
QString sql = QString("insert into user values('%1','%2');")
.arg(username).arg(password);
//执行sql语句
QSqlQuery query;
if(!query.exec(sql)){
QMessageBox::information(this,"提示",QString("注册失败:%1!").arg(query.lastError().text()));
}
else{
QMessageBox::information(this,"提示","注册成功!");
}
}
//登录
void SQLLogin::on_pushButton_login_clicked()
{
QString username = ui->lineEdit_username->text();
QString password = ui->lineEdit_password->text();
//创建加密对象
QCryptographicHash hash(QCryptographicHash::Md5);
//添加要加密的数据
hash.addData(password.toUtf8());
//获取加密的结果
QByteArray arr = hash.result();
password = arr.toHex();
qDebug()<<password;
QString sql = QString("select * from user where username='%1' and password='%2';")
.arg(username).arg(password);
//执行sql语句
QSqlQuery query;
if(!query.exec(sql)){
QMessageBox::warning(this,"提示","查询失败!");
return;
}
//查看有没有结果
if(query.next()){
QMessageBox::information(this,"提示","登录成功!");
}
else{
QMessageBox::information(this,"提示","用户名或密码错误!");
}
}
void SQLLogin::on_pushButton_exit_clicked()
{
this->close();
}