QT对sqlite数据库进行加密读取,并通过QT提供的用于与数据库交互的模型类,操作QT表格,实现高效交互,摒弃掉,查询数据库,跟进字段再创建表格的每个单元格插入表格,直接通过模型类自动绑定进行交互。
文中源码文件【获取方式】:关注公众号:利哥AI实例探险
给公众号发送 “qt表格视图数据库交互” 获取下载方式,免费,无套路,关注即可。公众号上有我手写的各类项目源码,均是免费提供,希望对您有帮助。
注意发送的关键词不能错,否则匹配不到对应资源,由于本人能力有限,难免有疏漏之处。
原文地址:【qt小系统】qt对sqlite数据库文件设置访问密码并以绑定QT表格视图的形式实现与数据库交互示例
系统演示
qt加密sqlite并通过QSqlModel实现数据库操作
1. qt通过开源库QtCipherSqlitePlugin对sqlite加密
- 下载源码并使用QT进行编译,源码github地址:https://github.com/devbean/QtCipherSqlitePlugin
- 编译成功后会在QtCipherSqlitePlugin/sqlitecipher/plugins/sqldrivers 目录下生成 sqlitecipher.dll 文件
- 将 sqlitecipher.dll 文件,复制到qt安装目录的对应目录下,例如:C:\Qt5152\5.15.2\mingw81_64\plugins\sqldrivers 下
- 编写代码,实现对sqlite数据库的加密设置
- 使用SQLiteStudio工具,输入密码后可以操作加密后的数据库数据
以下为QtCipherSqlitePlugin编译目录示例:
以下是我的C:\Qt5152\5.15.2\mingw81_64\plugins\sqldrivers目录示例:
以下为QT代码对sqlite数据库加密设置示例:
QSqlDatabase m_db = QSqlDatabase(QSqlDatabase::addDatabase("SQLITECIPHER", "ldb"));
m_db.setDatabaseName("sql_cipher.db");
// 加密数据库,如果不存在就创建test.db并用123456作为密码
// 第一个参数可以为空,因为它没有用处,第二个为密码
m_dbOpen = m_db.open("test", "123456");
if (m_dbOpen) {
m_sqlQuery = QSqlQuery(m_db);
m_sqlQuery.exec("PRAGMA page_size;");
if (m_sqlQuery.next()) { qDebug() << "使用的页大小:" << m_sqlQuery.value(0).toInt(); }
m_sqlQuery.exec("PRAGMA kdf_iter;");
if (m_sqlQuery.next()) { qDebug() << "KDF迭代次数:" << m_sqlQuery.value(0).toInt(); }
m_sqlQuery.exec("PRAGMA hmac_algorithm;");
if (m_sqlQuery.next()) { qDebug() << "HMAC算法:" << m_sqlQuery.value(0).toString(); }
m_sqlQuery.exec("PRAGMA cipher;"); // Cipher mode: "chacha20"
if (m_sqlQuery.next()) { qDebug() << "加密模式Cipher mode:" << m_sqlQuery.value(0).toString(); }
create_db_table();
}
以下是使用SQLiteStudio工具输入密码查看示例:
2. 使用QT提供的数据库交互模型操作sqlite
QSqlTableModel与QSqlQueryModel都是Qt提供的用于与数据库交互的模型类,但用途和设计目的有所不同。
- QSqlTableModel:是一个面向表格(Table-Oriented)的数据模型,主要用于直接操作数据库表。它提供了读写操作的完整支持,允许用户对表中的数据进行插入、更新、删除等操作,并将这些更改自动同步到数据库。
- QSqlQueryModel:是一个更通用的查询模型(Query-Oriented Model),主要用于执行任意 SQL 查询,并将结果以只读的形式展示给用户。它的特点是灵活性高,但不能直接用于对数据的增删改操作。
2.1 QSqlTableModel的用途
- 数据的增删改:允许对数据库表中的记录进行增删改操作。
- 自动提交:支持通过submitAll()提交对表数据的更改,或通过setEditStrategy()设置自动提交策略。
- 绑定表格视图:适合直接绑定到 QTableView 或其他表格视图进行数据展示,并与数据库实时同步。
2.2 QSqlQueryModel的用途
- 复杂查询:可以执行任意的 SQL 查询,包括多表联合查询、复杂的过滤条件、排序等。
- 只读显示:适合用于显示查询结果,但不能直接用于修改数据库。
- 灵活性:允许通过自定义 SQL 语句来获取数据,因此可以处理更复杂的数据库结构或需求。
3. QSqlTableModel实现交互
3.1 表格初始化
表格初始化,tableview绑定数据库表,设置表头实现数据库字段与表格的对应关系,将不想显示字段隐藏掉。
ui->tableView_student->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_student->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_student->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_student);
ui->tableView_student->setItemDelegate(centerDelegate);
ui->tableView_student->verticalHeader()->setVisible(false); // 隐藏行号
ui->tableView_student->setEditTriggers(QAbstractItemView::NoEditTriggers); // 完全禁用编辑触发器,包括双击、回车等
// 使用QSqlTableModel并与数据库连接
m_student_table_model = new QSqlTableModel(this, m_sql->m_db);
m_student_table_model->setTable("t_student");
m_student_table_model->select(); // 加载数据到tableView显示
ui->tableView_student->setModel(m_student_table_model);
m_student_table_model->setHeaderData(0, Qt::Horizontal, "数据库唯一标识Id");
m_student_table_model->setHeaderData(1, Qt::Horizontal, "学号");
m_student_table_model->setHeaderData(2, Qt::Horizontal, "学生姓名");
m_student_table_model->setHeaderData(3, Qt::Horizontal, "学生年龄");
m_student_table_model->setHeaderData(4, Qt::Horizontal, "教师ID");
ui->tableView_student->setColumnHidden(0, true);
ui->tableView_student->setColumnHidden(4, true);
// 允许输入范围 0-100
QIntValidator *validator = new QIntValidator(0, 100, ui->lineEdit_student_age);
ui->lineEdit_student_age->setValidator(validator);
3.2 数据添加
数据添加,关联table后,自动关联数据库的增加
QString sno = ui->lineEdit_student_sno->text();
QString name = ui->lineEdit_student_name->text();
int age = ui->lineEdit_student_age->text().toInt();
QSqlRecord record = m_student_table_model->record();
record.setValue("sno", sno);
record.setValue("name", name);
record.setValue("age", age);
m_student_table_model->insertRecord(-1, record); // 插入数据, -1表示在表末尾插入新纪录
m_student_table_model->submitAll(); // 提交更改
m_student_table_model->select();
3.3 数据修改
数据修改,关联model后,根据table的行号,自动关联表格及数据库的修改
QString sno = ui->lineEdit_student_sno->text();
QString name = ui->lineEdit_student_name->text();
int age = ui->lineEdit_student_age->text().toInt();
QSqlRecord record = m_student_table_model->record(m_stu_tableView_current_row);
record.setValue("sno", sno);
record.setValue("name", name);
record.setValue("age", age);
m_student_table_model->setRecord(m_stu_tableView_current_row, record);
if (!m_student_table_model->submitAll()) {
qDebug() << "Failed to update record:" << m_student_table_model->lastError().text();
return;
}
m_student_table_model->select();
3.4 数据删除
数据删除,关联model后,根据table的行号,自动关联表格及数据库的删除
if (!m_student_table_model->removeRow(m_stu_tableView_current_row)) {
return;
}
m_student_table_model->submitAll();
m_student_table_model->select();
4. QSqlQueryModel实现交互
4.1 表格初始化
tableview绑定数据库表,设置表头实现数据库字段与表格的对应关系,将不想显示字段隐藏掉。
ui->tableView_teacher->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_teacher->setSelectionBehavior(QAbstractItemView::SelectRows);
// 设置列可以自由伸缩并填满整个 QTableView
ui->tableView_teacher->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 设置每个单元格内容水平垂直居中对齐, 去掉Focus
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_teacher);
ui->tableView_teacher->setItemDelegate(centerDelegate);
ui->tableView_teacher->verticalHeader()->setVisible(false);// 隐藏行号
ui->tableView_teacher->setEditTriggers(QAbstractItemView::NoEditTriggers);// 完全禁用编辑触发器,包括双击、回车等
// 创建视图,并将模型设置到视图中
ui->tableView_teacher->setModel(&m_teacher_query_model);
// 查询并刷新QTableView
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);
// 使用setHeaderData()方法为表格的每一列设置自定义标题
m_teacher_query_model.setHeaderData(0, Qt::Horizontal, "数据库唯一标识Id");
m_teacher_query_model.setHeaderData(1, Qt::Horizontal, "工号");
m_teacher_query_model.setHeaderData(2, Qt::Horizontal, "教师姓名");
m_teacher_query_model.setHeaderData(3, Qt::Horizontal, "教师年龄");
m_teacher_query_model.setHeaderData(4, Qt::Horizontal, "职位");
// 隐藏不需要显示的列
ui->tableView_teacher->setColumnHidden(0, true);
4.2 数据添加
QString wkno = ui->lineEdit_teacher_sno->text();
QString name = ui->lineEdit_teacher_name->text();
int age = ui->lineEdit_teacher_age->text().toInt();
QString job = ui->lineEdit_teacher_job->text();
QSqlQuery query(m_sql->m_db);
query.prepare(QString(R"(
insert into %1 (wkno, name, age, JobTitle)
values (:wkno, :tea_name, :tea_age, :JobTitle)
)").arg("t_teacher"));
query.bindValue(":wkno", wkno);
query.bindValue(":tea_name", name);
query.bindValue(":tea_age", age);
query.bindValue(":JobTitle", job);
if (!query.exec()) {
qDebug() << "error=" << query.lastError().text();
return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);
4.3 数据修改
int id = ui->label_teacher_id->text().toInt();
QString wkno = ui->lineEdit_teacher_sno->text();
QString name = ui->lineEdit_teacher_name->text();
int age = ui->lineEdit_teacher_age->text().toInt();
QString job = ui->lineEdit_teacher_job->text();
QSqlQuery query(m_sql->m_db);
query.prepare("update t_teacher set wkno = :wkno, name = :tea_name, "
"age = :tea_age, JobTitle = :JobTitle "
"where id=:id");
query.bindValue(":id", id);
query.bindValue(":wkno", wkno);
query.bindValue(":tea_name", name);
query.bindValue(":tea_age", age);
query.bindValue(":JobTitle", job);
if (!query.exec()) {
qDebug() << "error=" << query.lastError().text();
return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);
4.4 数据删除
int id = ui->label_teacher_id->text().toInt();
QSqlQuery query(m_sql->m_db);
query.prepare("delete from t_teacher where id=:id");
query.bindValue(":id", id);
if (!query.exec()) {
qDebug() << "error=" << query.lastError().text();
return;
}
m_teacher_query_model.setQuery("select * from t_teacher", m_sql->m_db);
5. 使用QSqlQueryModel联合查询及自定义表头
ui->tableView_tea_stu->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView_tea_stu->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_tea_stu->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
CustomStyleDelegate *centerDelegate = new CustomStyleDelegate(ui->tableView_tea_stu);
ui->tableView_tea_stu->setItemDelegate(centerDelegate);
ui->tableView_tea_stu->verticalHeader()->setVisible(false);
ui->tableView_tea_stu->setEditTriggers(QAbstractItemView::NoEditTriggers);
// 设置查询模型
m_tea_stu_table_model = new QSqlQueryModel();
ui->tableView_tea_stu->setModel(m_tea_stu_table_model);
m_tea_stu_table_model->setQuery(R"(
SELECT
tea.wkno,
tea.name,
tea.age,
tea.JobTitle,
stu.name
FROM
t_teacher tea
JOIN
t_student stu
ON
tea.wkno = stu.teacherId
)", m_sql->m_db);
m_tea_stu_table_model->setHeaderData(0, Qt::Horizontal, "教师工号");
m_tea_stu_table_model->setHeaderData(1, Qt::Horizontal, "教师姓名");
m_tea_stu_table_model->setHeaderData(2, Qt::Horizontal, "教师年龄");
m_tea_stu_table_model->setHeaderData(3, Qt::Horizontal, "职称");
m_tea_stu_table_model->setHeaderData(4, Qt::Horizontal, "教授的学生姓名");
结束语
由于本人能力有限,难免有疏漏之处!
文中源码文件【获取方式】:关注公众号:利哥AI实例探险
给公众号发送 “qt表格视图数据库交互” 获取下载方式,免费,无套路,关注即可!!!
往期文章回顾
结束语
由于本人能力有限,难免有疏漏之处!
文中源码文件【获取方式】:关注公众号:利哥AI实例探险
给公众号发送 qt表格视图数据库交互 获取下载方式,免费,无套路,关注即可!!!