Qt中集成并使用SQLite数据库的超完整指南

2025-04-22 22:11:46 131
魁首哥

前言

sqlite 是一款轻量级、嵌入式的关系型数据库,无需独立的服务器进程,数据以文件形式存储,非常适合桌面和移动端应用的本地数据管理。qt 通过qt sql 模块提供了对 sqlite 的原生支持,开发者可以轻松实现数据库的增删改查、事务处理等操作。本文将详细介绍如何在 qt 中集成并使用 sqlite 数据库。

1. 环境配置与准备工作

1.1 启用 qt sql 模块

在 qt 项目文件(.pro)中添加 sql 模块依赖:

qt += sql

1.2 包含头文件

在代码中引入必要的类:

#include
#include
#include
#include

2. 连接 sqlite 数据库

2.1 创建并打开数据库

qsqldatabase db = qsqldatabase::adddatabase("qsqlite");
db.setdatabasename("my_database.db"); // 数据库文件名(或完整路径)

if (!db.open()) {
    qdebug() << "error: failed to open database:" << db.lasterror().text();
    return;
}
  • 说明

    • qsqlite是 qt 内置的 sqlite 驱动名称。

    • 如果文件不存在,sqlite 会自动创建新数据库。

2.2 关闭数据库

db.close(); // 显式关闭连接(通常不需要,程序退出时自动关闭)

3. 执行 sql 操作

3.1 创建表

qsqlquery query;
query.exec("create table if not exists users ("
          "id integer primary key autoincrement,"
          "name text not null,"
          "age integer,"
          "email text unique)");

3.2 插入数据

直接执行 sql

query.exec("insert into users (name, age, email) values ('alice', 30, 'alice@example.com')");

使用预处理语句(防 sql 注入)

query.prepare("insert into users (name, age, email) values (?, ?, ?)");
query.addbindvalue("bob");
query.addbindvalue(25);
query.addbindvalue("bob@example.com");
query.exec();

3.3 查询数据

if (query.exec("select id, name, age from users where age > 20")) {
    while (query.next()) {
        int id = query.value(0).toint();
        qstring name = query.value("name").tostring();
        int age = query.value(2).toint();
        qdebug() << "user:" << id << name << age;
    }
} else {
    qdebug() << "query error:" << query.lasterror().text();
}

3.4 更新与删除数据

// 更新
query.exec("update users set age = 31 where name = 'alice'");

// 删除
query.exec("delete from users where email is null");

4. 事务处理

通过事务确保多个操作的原子性:

db.transaction(); // 开始事务

qsqlquery query;
query.exec("update account set balance = balance - 100 where id = 1");
query.exec("update account set balance = balance + 100 where id = 2");

if (/* 检查操作是否成功 */) {
    db.commit();   // 提交事务
} else {
    db.rollback(); // 回滚事务
}

5. 使用模型-视图(model-view)编程

qt 提供了qsqltablemodelqsqlquerymodel,方便将数据库与 ui 组件(如qtableview)绑定。

5.1 显示表格数据

qsqltablemodel *model = new qsqltablemodel(this);
model->settable("users");
model->setfilter("age > 20");
model->select();

qtableview *view = new qtableview;
view->setmodel(model);
view->show();

5.2 编辑并保存修改

model->seteditstrategy(qsqltablemodel::onmanualsubmit);
// 用户通过视图修改数据后调用:
model->submitall(); // 提交所有更改到数据库

6. 错误处理与调试

6.1 捕获数据库错误

if (!query.exec("invalid sql")) {
    qdebug() << "sql error:" << query.lasterror().text();
    qdebug() << "executed sql:" << query.lastquery();
}

6.2 查看支持的数据库驱动

qdebug() << "available drivers:" << qsqldatabase::drivers();
// 输出示例:("qsqlite", "qmysql", "qpsql")

7. 高级技巧与注意事项

7.1 批量插入优化

使用事务加速大批量插入:

db.transaction();
qsqlquery query;
query.prepare("insert into users (name) values (?)");
for (const qstring &name : nameslist) {
    query.addbindvalue(name);
    query.exec();
}
db.commit();

7.2 多线程访问

  • sqlite 默认不支持多线程同时写入,需通过qsqldatabase::clonedatabase为每个线程创建独立连接。

  • 在子线程中使用数据库时,确保在子线程内打开连接。

7.3 数据库迁移

  • 使用user_version字段管理数据库版本:

    query.exec("pragma user_version = 1"); // 设置版本号
    query.exec("pragma user_version");     // 读取版本号

8. 常见问题解答

q1:数据库文件被锁定了怎么办?

  • 确保所有qsqlqueryqsqldatabase对象在使用后及时释放。

  • 避免多线程同时写入同一连接。

q2:如何防止 sql 注入?

  • 始终使用prepare()addbindvalue()替代字符串拼接。

q3:查询性能慢如何优化?

  • 为常用查询字段添加索引。

  • 减少频繁的小事务,合并为批量操作。

9. 完整示例代码

#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    qcoreapplication a(argc, argv);

    qsqldatabase db = qsqldatabase::adddatabase("qsqlite");
    db.setdatabasename("test.db");
    
    if (!db.open()) {
        qdebug() << "database error:" << db.lasterror().text();
        return -1;
    }

    qsqlquery query;
    query.exec("create table if not exists books ("
               "id integer primary key,"
               "title text,"
               "author text)");

    query.prepare("insert into books (title, author) values (?, ?)");
    query.addbindvalue("qt programming");
    query.addbindvalue("john doe");
    query.exec();

    query.exec("select * from books");
    while (query.next()) {
        qdebug() << "book:" << query.value("title").tostring()
                 << "by" << query.value("author").tostring();
    }

    db.close();
    return a.exec();
}

10. 总结

qt 的 sqlite 支持使得本地数据管理变得简单高效。核心要点包括:

  • 使用qsqldatabase管理数据库连接。

  • 通过qsqlquery执行 sql 语句并处理结果。

  • 利用事务保证数据一致性。

  • 结合模型-视图框架快速构建 ui 界面。

官方文档参考

  • qt sql module

  • sqlite 官方文档

到此这篇关于qt中集成并使用sqlite数据库的文章就介绍到这了,更多相关qt集成使用sqlite数据库内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

分享
海报
131
上一篇:使用Redis实现实时排行榜的示例 下一篇:MySQL存储引擎InnoDB架构原理和执行流程

忘记密码?

图形验证码