怎样在Qt下连接读写sqlite数据库

本文介绍如何使用Qt进行SQLite数据库的基本操作,包括创建数据库连接、打开数据库、执行数据的插入和查询操作。
  1. 这里以学生信息的录入与读取来作为演示,主要目的是演示数据库的操作,至于数据的显示等不在演示范围内,请您自行研究。

    首先,在Qt中建立一个图形界面的程序项目。

    怎样在Qt下连接读写sqlite数据库
  2. 然后,我们在命令行下用sqlite命令创建了数据库 C:\StudentInfo\sutdentdata.db,并且建立了一个数据库表student,该表有四个字段ID、Name、Sex、Age,未向表中添加任何数据。

    关于sqlite的简单使用,可以参考我们的另一篇经验。

    怎样在Qt下连接读写sqlite数据库
  3. 在读写SQLite数据库中,我们最主要用到的是QSqlDatabase类及QSqlQuery类,前者负责创建数据库连接并打开数据库,后者负责执行查询操作。实际上前者也可以进行查询操作并将结果返回给QSqlQuery对象,但是Qt并不建议这么做。

    在干活前,依然是先看看Assitant,这是培养独立解决问题的一个好习惯。

    怎样在Qt下连接读写sqlite数据库
    怎样在Qt下连接读写sqlite数据库
  4. 好,下面给  录入  按钮的点击事件编写代码。关于如何给按钮的某一事件进行编码,可以参考我们另一篇经验。

    首先在.pro文件中加上sql,然后别忘了#include <QSqlDatabase>以及#include <QSqlQuery>。

    好了,下面在录入按钮的槽中加入如下代码:

    QSqlDatabase mydb=QSqlDatabase::addDatabase("QSQLITE","wconntosqlite");

        mydb.setDatabaseName("c:\\StudentInfo\\studentdata.db");

        if(mydb.open())

        {

            QSqlQuery query(mydb);

            QString sqlstr="insert into student (ID,Name,Sex,Age) values ('"

                    +ui->le_id->text()+"','"

                    +ui->le_name->text()+"','"

                    +ui->le_sex->text()+"',"

                    +ui->le_age->text()+")";

            bool isok=query.exec(sqlstr);

            if(isok)

                qDebug()<<"数据写入成功";

        }

    上面我们先调用了QSqlDatabase的静态函数addDatabase创建了一个名为wconntosqlite的连接。然后给其传递数据库名称。

    如果数据库打开成功,就创建一个关联的QSqlQuery对象,最后由QSqlQuery来执行插入数据工作。

    特别注意:QSqlQuery对象的创建必须在mydb  open成功以后才行,否则会出错。

    我们来看看效果如何。

    怎样在Qt下连接读写sqlite数据库
  5. 我们接着来写查询按钮的代码,输入以下代码:

    QSqlDatabase mydb=QSqlDatabase::addDatabase("QSQLITE","rconntosqlite");

        mydb.setDatabaseName("c:\\StudentInfo\\studentdata.db");

        if(mydb.open())

        {

            QSqlQuery query(mydb);

            QString sqlstr="select * from student";

            bool isok=query.exec(sqlstr);

            if(isok)

                qDebug()<<"数据读取成功";

            query.first();

            QString result="学号:"+query.value(0).toString()+"  "

                    +"姓名:"+query.value(1).toString()+"  "

                    +"性别:"+query.value(2).toString()+"  "

                    +"年龄:"+query.value(3).toString();

            ui->lbl_query->setText(result);

        }

    与写入数据基本差不多,这里需要特别注意的是query.first();。看看Assistant怎么说的就知道了。原来,query对象在执行完查询语句后,query的位置被置于一个不可用的位置,如果想从query中获取数据,需要设置query到一个可用的记录中才行。方法有好几种,这里我们用了first()成员函数。

    好,来看看运行结果。

    可以看到软件读取的数据与控制台窗口的数据是一致的。

    怎样在Qt下连接读写sqlite数据库
    怎样在Qt下连接读写sqlite数据库
  6. 我们来总结下Qt操作SQLite数据库的五步走法决:

    第一步,建立一个连接:QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");

    第二步,关联数据库文件:db.setDatabaseName("这里你的数据库文件路径")

    第三步,打开数据库:db.open()

    第四步,如果数据库打开成功,就建立一个相关联的QSqlQuery对象:QSqlQuery query(db)

    第五步,执行SQL语句:query.exec("你的SQL语句字符串")

<think>我们使用Qt的SQL模块来操作SQLite数据库,特别是处理多表关联数据。根据引用[2],Qt提供了三种访问SQLite数据库的方式:QSqlQuery(底层操作)、QSqlQueryModel(只读模型)和QSqlTableModel(可编辑模型)。对于多表关联,我们通常使用QSqlRelationalTableModel,它允许我们在一个表中使用外键引用另一个表,并在视图中显示关联字段(如部门名称而不是部门ID)。 下面是一个使用Qt C++的示例,展示如何创建两个关联的表(部门表和员工表),并使用QSqlRelationalTableModel来显示和编辑员工表,其中部门字段显示为部门名称(通过外键关联)。 步骤: 1. 创建并连接SQLite数据库。 2. 创建两个表:department(部门表)和employee(员工表),其中employee表包含一个指向department表的外键。 3. 使用QSqlRelationalTableModel设置员工表,并将部门ID字段关联到部门表的名称字段。 4. 使用QTableView显示数据,并设置关系委托(QSqlRelationalDelegate)以便在编辑时提供下拉框选择部门。 注意:在Qt中,我们需要包含相应的头文件,并在项目文件(.pro)中添加`QT += sql`。 以下是完整的示例代码:</think>### Qt C++ SQLite 多表关联数据读写示例 下面是一个完整的Qt C++示例,展示如何操作包含多表关联的SQLite数据库。该示例包含部门表(department)和员工表(employee),通过外键实现关联操作: ```cpp #include <QApplication> #include <QMainWindow> #include <QTableView> #include <QVBoxLayout> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlRelationalTableModel> #include <QSqlRelation> #include <QSqlRelationalDelegate> #include <QMessageBox> #include <QDebug> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { setWindowTitle("SQLite 多表关联示例"); setGeometry(100, 100, 800, 600); // 初始化数据库 if (!initDatabase()) { QMessageBox::critical(this, "错误", "无法初始化数据库"); return; } // 创建UI QWidget *centralWidget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout(centralWidget); // 部门表视图 deptView = new QTableView(this); deptModel = new QSqlRelationalTableModel(this); deptModel->setTable("department"); deptModel->select(); deptView->setModel(deptModel); // 员工表视图(带关联) empView = new QTableView(this); empModel = new QSqlRelationalTableModel(this); empModel->setTable("employee"); // 设置部门ID的关系(显示部门名称而非ID) empModel->setRelation(2, QSqlRelation("department", "id", "name")); empModel->select(); // 设置表头 empModel->setHeaderData(0, Qt::Horizontal, "ID"); empModel->setHeaderData(1, Qt::Horizontal, "姓名"); empModel->setHeaderData(2, Qt::Horizontal, "部门"); empModel->setHeaderData(3, Qt::Horizontal, "薪资"); // 设置关系委托(编辑时显示下拉框) empView->setItemDelegate(new QSqlRelationalDelegate(empView)); empView->setModel(empModel); // 添加按钮 QPushButton *btnAddDept = new QPushButton("添加测试部门", this); connect(btnAddDept, &QPushButton::clicked, this, &MainWindow::addDepartment); QPushButton *btnAddEmp = new QPushButton("添加测试员工", this); connect(btnAddEmp, &QPushButton::clicked, this, &MainWindow::addEmployee); // 布局 layout->addWidget(deptView); layout->addWidget(empView); layout->addWidget(btnAddDept); layout->addWidget(btnAddEmp); setCentralWidget(centralWidget); } private: bool initDatabase() { // 创建SQLite数据库连接 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("company.db"); if (!db.open()) { qDebug() << "无法打开数据库:" << db.lastError().text(); return false; } // 创建表结构 QSqlQuery query; query.exec("CREATE TABLE IF NOT EXISTS department (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT NOT NULL)"); query.exec("CREATE TABLE IF NOT EXISTS employee (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT NOT NULL," "department_id INTEGER," "salary REAL," "FOREIGN KEY(department_id) REFERENCES department(id))"); // 插入示例数据 query.exec("INSERT OR IGNORE INTO department (name) VALUES ('研发部')"); query.exec("INSERT OR IGNORE INTO department (name) VALUES ('市场部')"); query.exec("INSERT OR IGNORE INTO department (name) VALUES ('财务部')"); query.exec("INSERT OR IGNORE INTO employee (name, department_id, salary) " "VALUES ('张三', 1, 15000.0)"); query.exec("INSERT OR IGNORE INTO employee (name, department_id, salary) " "VALUES ('李四', 2, 12000.0)"); return true; } void addDepartment() { QSqlQuery query; query.prepare("INSERT INTO department (name) VALUES (?)"); query.addBindValue("新部门"); if (!query.exec()) { qDebug() << "添加部门失败:" << query.lastError().text(); } deptModel->select(); } void addEmployee() { QSqlQuery query; query.prepare("INSERT INTO employee (name, department_id, salary) " "VALUES (?, ?, ?)"); query.addBindValue("新员工"); query.addBindValue(1); // 默认添加到研发部 query.addBindValue(10000.0); if (!query.exec()) { qDebug() << "添加员工失败:" << query.lastError().text(); } empModel->select(); } QTableView *deptView; QTableView *empView; QSqlRelationalTableModel *deptModel; QSqlRelationalTableModel *empModel; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 检查SQLite驱动是否可用 if (!QSqlDatabase::isDriverAvailable("QSQLITE")) { QMessageBox::critical(nullptr, "错误", "SQLite驱动不可用"); return -1; } MainWindow window; window.show(); return app.exec(); } #include "main.moc" ``` ### 关键功能说明 1. **多表关联实现**: - 使用 `QSqlRelationalTableModel` 建立表间关系[^2] - `setRelation()` 方法将部门ID映射为部门名称: ```cpp empModel->setRelation(2, QSqlRelation("department", "id", "name")); ``` - 外键约束确保数据完整性: ```sql FOREIGN KEY(department_id) REFERENCES department(id) ``` 2. **关系委托**: ```cpp empView->setItemDelegate(new QSqlRelationalDelegate(empView)); ``` 在编辑时显示部门下拉列表而非直接输入ID[^2] 3. **多表查询示例**: ```cpp QSqlQuery query; query.exec("SELECT e.id, e.name, d.name AS dept_name, e.salary " "FROM employee e " "JOIN department d ON e.department_id = d.id"); while (query.next()) { int id = query.value(0).toInt(); QString name = query.value(1).toString(); QString dept = query.value(2).toString(); double salary = query.value(3).toDouble(); qDebug() << id << name << dept << salary; } ``` 4. **事务处理**: ```cpp QSqlDatabase::database().transaction(); // 开始事务 try { // 执行多个SQL操作 QSqlDatabase::database().commit(); // 提交事务 } catch (...) { QSqlDatabase::database().rollback(); // 回滚事务 } ``` ### 项目配置(.pro文件) ```qmake QT += core gui sql CONFIG += c++17 TARGET = SqliteExample TEMPLATE = app SOURCES += main.cpp ``` ### 注意事项 1. **驱动检查**: ```cpp if (!QSqlDatabase::isDriverAvailable("QSQLITE")) { // 处理错误 } ``` 2. **错误处理**: ```cpp if (!query.exec()) { qDebug() << "SQL错误:" << query.lastError().text(); } ``` 3. **模型更新**: - 修改数据后调用 `model->submitAll()` 提交更改 - 调用 `model->select()` 刷新视图 4. **性能优化**: - 批量操作使用事务 - 大数据集使用分页加载 - 建立索引加速查询 ### 相关工具 - SQLite可视化工具:DB Browser for SQLite[^1] - 数据库管理组件:feiyangqingyun的DBTool[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值