QT读写Sqlite数据库的三种方式

     QT对一些基本的数据库的访问封装,可谓是极大的方便的我们开发人员,现在我们就来说下QT对Sqlite这个数据库的读写,Sqlite是一个比较小型的本地数据库,对于保存一些软件配置参数或量不是很大的数据是相当的方便,Qt本身已经自带了Sqlite的驱动,直接使用相关的类库即可,这篇我们主要来说明QT访问Sqlite数据库的三种方式(即使用三种类库去访问),分别为QSqlQuery、QSqlQueryModel、QSqlTableModel,对于这三种类库,可看为一个比一个上层,也就是封装的更厉害,甚至第三种QSqlTableModel,根本就不需要开发者懂SQL语言,也能操作Sqlite数据库。

1、首先使用QSqlQuery来访问
      我们先要在工程中包含与数据库相关的几个头文件#include <QtSql/QSqlDatabase> 、#include <QtSql/QSqlRecord>、#include <QtSql/QSqlQuery>
访问的数据库内容结构为:

#include <QtWidgets/QApplication>
#include <QCoreApplication>
#include <QDebug>

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlRecord>

typedef struct _testInfo //假定数据库存储内容
{
    QString UsreName;
    QString IP;
    QString Port;
    QString PassWord;
    QString Type;

}testInfo;

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

    QVector<testInfo> infoVect; //testInfo向量,用于存储数据库查询到的数据

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  

    db.setDatabaseName(QApplication::applicationDirPath() + "/CONFIG/" + "CONFIG.db");
    if (!db.open())
    {
    	return 0;
    }

/**************************使用QSqlQuery操作数据库**************************/
    QSqlQuery query;	//执行操作类对象

    //查询数据
    query.prepare("SELECT * FROM T_USER_MANAGE");
    query.exec();	//执行
	
    QSqlRecord recode = query.record();		//recode保存查询到一些内容信息,如表头、列数等等
    int column = recode.count();			//获取读取结果的列数	
    QString s1 = recode.fieldName(0);		//获取第0列的列名

    while (query.next())
    {
	    testInfo tmp;
	    tmp.UsreName = query.value("UsreName").toString();
	    tmp.IP = query.value("IP").toString();
	    tmp.Port = query.value("Port").toString();
	    tmp.PassWord = query.value("PassWord").toString();
	    tmp.Type = query.value("Type").toString();

	    infoVect.push_back(tmp);   //将查询到的内容存到testInfo向量中
    }

    for (int i=0; i<infoVect.size(); i++)    //打印输出
    {
	    qDebug() << infoVect[i].UsreName << ":"	\
	             << infoVect[i].IP << ":"		\
		         << infoVect[i].Port << ":"		\
		         << infoVect[i].PassWord << ":" \
		         << infoVect[i].Type;
	}
	
	//插入数据
    query.prepare("INSERT INTO T_USER_MANAGE (UsreName, IP, Port, PassWord, Type) VALUES (:UsreName, :IP, :Port, :PassWord, :Type)");
    query.bindValue(":UserName", "user4");	//给每个插入值标识符设定具体值
    query.bindValue(":IP", "192.168.1.5");
    query.bindValue(":Port", "5004");
    query.bindValue(":PassWord", "55555");
    query.bindValue(":Type", "operator");
    query.exec();	


    //更改表中 UserName=user4 的Type属性为admin
    query.prepare("UPDATE T_USER_MANAGE SET Type='admin' WHERE UserName='user4'");
    query.exec();

    //删除表中 UserName=user4的用户信息
    query.prepare("DELETE FROM T_USER_MANAGE WHERE UserName='user4'");
    query.exec();

#endif
/**************************使用QSqlQuery操作数据库END***********************/

编译输出:

2、使用QSqlQueryModel来访问

    QSqlQueryModel类带有Model字样,相信你已经猜到我们可以用他来关联试图,就能把数据库的内容显示到视图上,当然,常规的操作也是可以的,但是我们只说说怎么用这个类来把数据库中的内容显示到是视图中,这里我们选择的视图类为QTableView,直接上代码吧
 

#include <QtWidgets/QApplication>
#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QTableView>

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQueryModel>

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

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

    db.setDatabaseName(QApplication::applicationDirPath() + "/CONFIG/" + "CONFIG.db");
    if (!db.open())
    {
    	retur
<think>我们被要求生成相关问题,但用户当前的问题是关于Qt SQLite多表关联数据读写的示例代码。因此,在回答完用户问题后,我们需要生成相关问题。 根据用户需求,我们需要提供使用Qt读写SQLite数据库中多表关联数据的示例代码。我们将使用Qt的SQL模块,特别是QSqlQuery和QSqlTableModel(或QSqlRelationalTableModel)来实现多表关联操作。 步骤: 1. 创建数据库和表(示例中我们将创建两个表:部门表和员工表,员工表通过部门ID关联部门表) 2. 使用QSqlDatabase连接SQLite数据库 3. 使用QSqlQuery执行多表关联查询 4. 使用QSqlRelationalTableModel实现带关联的表模型,并绑定到QTableView 注意:由于用户要求多表关联,我们将展示两种方式:直接使用SQL查询和使用关系模型。 示例代码将包括: - 创建数据库和表(如果不存在) - 插入示例数据 - 执行关联查询并打印结果 - 使用QSqlRelationalTableModel展示关联数据 由于代码较长,我们将分步骤编写。 首先,我们创建一个Qt应用程序,并设置数据库连接。 然后,我们创建两个表: - department (id, name) - employee (id, name, department_id) 接着,我们插入一些示例数据。 最后,我们展示两种查询方式。 注意:我们使用PySide6,但代码与PyQt类似,只需稍作修改。 由于用户没有指定使用C++还是Python,但引用中出现了PySide6,因此我们使用Python(PySide6)编写示例。 让我们开始编写代码。</think>### Qt SQLite 多表关联数据读写示例 下面是一个完整的 PySide6 示例,展示如何实现 SQLite 多表关联操作。该示例包含部门表(department)和员工表(employee),通过外键关联实现数据读写: ```python import sys from PySide6.QtWidgets import QApplication, QMainWindow, QTableView, QVBoxLayout, QWidget, QPushButton from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlRelationalTableModel, QSqlRelation from PySide6.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("SQLite 多表关联示例") self.setGeometry(100, 100, 800, 600) # 创建数据库连接 self.db = QSqlDatabase.addDatabase("QSQLITE") self.db.setDatabaseName("company.db") if not self.db.open(): print("无法打开数据库") sys.exit(1) # 初始化数据库 self.init_db() # 创建UI central_widget = QWidget() layout = QVBoxLayout() # 部门表视图 self.dept_view = QTableView() self.dept_model = QSqlRelationalTableModel() self.dept_model.setTable("department") self.dept_model.select() self.dept_view.setModel(self.dept_model) # 员工表视图(带关联) self.emp_view = QTableView() self.emp_model = QSqlRelationalTableModel() self.emp_model.setTable("employee") # 设置部门ID的关系(显示部门名称而非ID) self.emp_model.setRelation(2, QSqlRelation("department", "id", "name")) self.emp_model.select() # 设置表头 self.emp_model.setHeaderData(0, Qt.Horizontal, "ID") self.emp_model.setHeaderData(1, Qt.Horizontal, "姓名") self.emp_model.setHeaderData(2, Qt.Horizontal, "部门") self.emp_model.setHeaderData(3, Qt.Horizontal, "薪资") self.emp_view.setModel(self.emp_model) # 添加按钮 self.btn_add_dept = QPushButton("添加测试部门") self.btn_add_dept.clicked.connect(self.add_department) self.btn_add_emp = QPushButton("添加测试员工") self.btn_add_emp.clicked.connect(self.add_employee) # 布局 layout.addWidget(self.dept_view) layout.addWidget(self.emp_view) layout.addWidget(self.btn_add_dept) layout.addWidget(self.btn_add_emp) central_widget.setLayout(layout) self.setCentralWidget(central_widget) def init_db(self): """初始化数据库和表结构""" query = QSqlQuery() # 创建部门表 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) """) def add_department(self): """添加新部门""" query = QSqlQuery() query.prepare("INSERT INTO department (name) VALUES (?)") query.addBindValue("新部门") query.exec() self.dept_model.select() def add_employee(self): """添加新员工""" query = QSqlQuery() query.prepare(""" INSERT INTO employee (name, department_id, salary) VALUES (?, ?, ?) """) query.addBindValue("新员工") query.addBindValue(1) # 默认添加到研发部 query.addBindValue(10000.0) query.exec() self.emp_model.select() def closeEvent(self, event): """关闭时释放数据库连接""" self.db.close() super().closeEvent(event) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) ``` ### 关键功能说明 1. **多表关联实现**: - 使用 `QSqlRelationalTableModel` 建立表间关系 - `setRelation()` 方法将部门ID映射为部门名称 - 外键约束确保数据完整性:`FOREIGN KEY(department_id) REFERENCES department(id)` 2. **数据展示**: - 部门表显示原始数据 - 员工表自动将部门ID转换为部门名称显示 - 表头自定义:`setHeaderData()` 设置中文列名 3. **数据操作**: - 模型自动处理关联数据的读写 - 添加新记录时自动维护外键关系 - 使用 `prepare()` 防止 SQL 注入 4. **事务支持**: ```python self.db.transaction() # 开始事务 try: # 执行多个SQL操作 self.db.commit() # 提交事务 except: self.db.rollback() # 回滚事务 ``` ### 多表查询示例 如果需要执行复杂的多表联合查询,可以使用 `QSqlQuery`: ```python # 执行JOIN查询 query = QSqlQuery() query.exec(""" SELECT employee.id, employee.name, department.name AS dept_name, employee.salary FROM employee JOIN department ON employee.department_id = department.id WHERE salary > 10000 """) while query.next(): emp_id = query.value(0) emp_name = query.value(1) dept_name = query.value(2) salary = query.value(3) print(f"{emp_id} | {emp_name} | {dept_name} | {salary}") ``` ### 注意事项 1. **模型更新**: - 修改数据后调用 `model.submitAll()` 提交更改 - 调用 `model.select()` 刷新视图 2. **关系委托**: ```python from PySide6.QtSql import QSqlRelationalDelegate # 在视图中设置关系委托 delegate = QSqlRelationalDelegate(self.emp_view) self.emp_view.setItemDelegate(delegate) ``` 这样可以在编辑时显示部门下拉列表而非直接输入ID[^2] 3. **错误处理**: ```python if not query.exec(): print("SQL错误:", query.lastError().text()) ``` [^1]: 使用 `QSqlRelationalTableModel` 可以简化多表关联操作,自动处理外键关系。 [^2]: `QSqlRelationalDelegate` 提供关联字段的下拉选择功能,提升用户体验。 --- ### 相关问题 1. **如何实现 QtSQLite 数据库的加密?** Qt 本身不直接支持 SQLite 加密,但可通过第三方库如 SQLCipher 或 Qt 插件实现。 2. **Qt 中如何实现主从表视图?** 可使用 `QSqlRelationalTableModel` 配合 `QDataWidgetMapper`,或通过选择主表行时刷新从表模型。 3. **如何优化 Qt SQLite 的大数据量操作性能?** 建议使用事务批量操作、建立合适索引、分页加载数据,以及异步查询防止界面卡顿。 4. **Qt 中如何备份和恢复 SQLite 数据库?** 可通过 `QFile.copy()` 复制数据库文件,或使用 `.dump` 命令导出 SQL 脚本。
评论 15
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值