一、Qt数据库模块概述
Qt提供了Qt SQL模块,用于数据库编程。该模块支持多种数据库系统,包括MySQL、PostgreSQL、SQLite、Oracle等,通过统一的API接口进行操作,实现了数据库操作的抽象化。
1.1 主要类介绍
- QSqlDatabase:管理数据库连接
- QSqlQuery:执行SQL语句
- QSqlTableModel:操作单个数据库表的高级接口
- QSqlRelationalTableModel:支持外键的表模型
- QSqlQueryModel:只读的查询结果模型
- QSqlError:提供数据库错误信息
1.2 数据库驱动
Qt通过驱动插件支持不同的数据库系统,常用驱动包括:
- QSQLITE:SQLite数据库
- QMYSQL:MySQL数据库
- QPSQL:PostgreSQL数据库
- QODBC:ODBC接口(可连接多种数据库)
二、连接数据库
2.1 连接SQLite数据库
SQLite是轻量级嵌入式数据库,无需单独的服务器进程,适合小型应用。
示例:连接SQLite数据库
#include <QSqlDatabase>
#include <QSqlError>
#include <QDebug>
bool connectToDatabase()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydatabase.db");
if (!db.open()) {
qDebug() << "Cannot open database:" << db.lastError().text();
return false;
}
qDebug() << "Database connected successfully";
return true;
}
2.2 连接MySQL数据库
MySQL是常用的开源关系型数据库,需要安装服务器并创建数据库。
示例:连接MySQL数据库
bool connectToMySQLDatabase()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("mydatabase");
db.setUserName("username");
db.setPassword("password");
db.setPort(3306);
if (!db.open()) {
qDebug() << "Cannot open database:" << db.lastError().text();
return false;
}
qDebug() << "MySQL database connected successfully";
return true;
}
2.3 多数据库连接
可以同时连接多个数据库,每个连接需要指定唯一的连接名。
示例:多数据库连接
// 第一个连接
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "Connection1");
db1.setDatabaseName("database1.db");
db1.open();
// 第二个连接
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "Connection2");
db2.setDatabaseName("database2.db");
db2.open();
// 使用特定连接的查询
QSqlQuery query1(db1);
QSqlQuery query2(db2);
三、执行SQL查询
3.1 使用QSqlQuery执行简单查询
QSqlQuery用于执行SQL语句并处理结果。
示例:创建表
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS persons ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT, "
"age INTEGER)");
if (query.lastError().isValid()) {
qDebug() << "Error creating table:" << query.lastError().text();
}
示例:插入数据
// 方法1:直接执行SQL
query.exec("INSERT INTO persons (name, age) VALUES ('John', 30)");
// 方法2:使用预处理语句(更安全,防止SQL注入)
query.prepare("INSERT INTO persons (name, age) VALUES (:name, :age)");
query.bindValue(":name", "Alice");
query.bindValue(":age", 25);
query.exec();
示例:查询数据
query.exec("SELECT * FROM persons");
while (query.next()) {
int id = query.value(0).toInt();
QString name = query.value(1).toString();
int age = query.value(2).toInt();
qDebug() << "ID:" << id << "Name:" << name << "Age:" << age;
}
3.2 使用事务处理
事务可以确保一组操作要么全部成功,要么全部失败。
示例:使用事务
QSqlDatabase::database().transaction(); // 开始事务
QSqlQuery query;
query.exec("INSERT INTO persons (name, age) VALUES ('Bob', 35)");
query.exec("INSERT INTO persons (name, age) VALUES ('Charlie', 40)");
if (query.lastError().isValid()) {
QSqlDatabase::database().rollback(); // 回滚事务
qDebug() << "Transaction failed:" << query.lastError().text();
} else {
QSqlDatabase::database().commit(); // 提交事务
qDebug() << "Transaction succeeded";
}
四、使用模型视图类操作数据库
Qt提供了高级的模型视图类,使数据库操作更加便捷。
4.1 QSqlTableModel
用于操作单个数据库表的读写模型。
示例:使用QSqlTableModel
#include <QSqlTableModel>
#include <QTableView>
// 创建模型
QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("persons");
model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 手动提交更改
// 加载数据
if (!model->select()) {
qDebug() << "Error loading data:" << model->lastError().text();
}
// 显示在表格视图中
QTableView *view = new QTableView;
view->setModel(model);
view->show();
// 修改数据
model->insertRow(model->rowCount());
model->setData(model->index(model->rowCount()-1, 1), "David");
model->setData(model->index(model->rowCount()-1, 2), 28);
// 提交更改
if (!model->submitAll()) {
qDebug() << "Error submitting changes:" << model->lastError().text();
}
4.2 QSqlRelationalTableModel
支持外键关联的表模型。
示例:使用QSqlRelationalTableModel
// 假设我们有两个表:departments和employees
// employees表中有一个department_id字段,关联到departments表的id字段
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this);
model->setTable("employees");
model->setRelation(2, QSqlRelation("departments", "id", "name")); // 设置外键关系
model->setHeaderData(0, Qt::Horizontal, "ID");
model->setHeaderData(1, Qt::Horizontal, "Name");
model->setHeaderData(2, Qt::Horizontal, "Department");
if (!model->select()) {
qDebug() << "Error loading data:" << model->lastError().text();
}
QTableView *view = new QTableView;
view->setModel(model);
view->show();
五、错误处理
数据库操作可能会失败,必须进行错误检查。
示例:错误处理
QSqlQuery query;
if (!query.exec("SELECT * FROM non_existent_table")) {
QSqlError error = query.lastError();
qDebug() << "Query error:" << error.text();
qDebug() << "Error type:" << error.type();
qDebug() << "Error number:" << error.number();
}
六、SQLite数据库示例应用
下面是一个完整的SQLite数据库操作示例,包括创建表、插入数据、查询数据和使用模型视图显示数据。
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlTableModel>
#include <QTableView>
#include <QDebug>
bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "Cannot open database:" << db.lastError().text();
return false;
}
// 创建表
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS contacts ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT, "
"phone TEXT, "
"email TEXT)");
if (query.lastError().isValid()) {
qDebug() << "Error creating table:" << query.lastError().text();
return false;
}
return true;
}
void insertSampleData()
{
QSqlQuery query;
query.prepare("INSERT INTO contacts (name, phone, email) VALUES (:name, :phone, :email)");
// 插入示例数据
query.bindValue(":name", "John Doe");
query.bindValue(":phone", "123-456-7890");
query.bindValue(":email", "john@example.com");
query.exec();
query.bindValue(":name", "Jane Smith");
query.bindValue(":phone", "098-765-4321");
query.bindValue(":email", "jane@example.com");
query.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (!createConnection())
return 1;
insertSampleData();
// 使用模型视图显示数据
QSqlTableModel model;
model.setTable("contacts");
model.select();
QTableView view;
view.setModel(&model);
view.resize(600, 400);
view.show();
return a.exec();
}
七、总结
Qt SQL模块提供了强大而灵活的数据库编程功能,通过统一的API可以连接和操作多种数据库系统。QSqlDatabase类用于管理数据库连接,QSqlQuery类用于执行SQL语句,而模型视图类(如QSqlTableModel和QSqlRelationalTableModel)则提供了更高级的数据库操作方式。在实际开发中,应根据具体需求选择合适的数据库系统和操作方式,并注意错误处理和事务管理。掌握Qt数据库编程技术,可以开发出数据驱动的应用程序,实现数据的存储、查询和管理功能。