目录
Qt SQL提供的数据库驱动
SQLite数据库
Qt SQL模块的主要类
数据库相关数据模型类的继承关系
QSqlQueryModel
QSqlTableModel
QSqlRelationalTableModel
QSqlQuery
打开数据表
表示记录的类QSqlRecord
表示字段的类QSqlField
SQLite是一种无需服务器、无需进行任何配置的数据库,所有的数据表、索引等数据库元素全都存储在一个文件里,在应用程序里使用SQLite数据库就完全可以当作一个文件来使用。SQLite是可以跨平台使用的数据库,在不同平台之间可以随意复制数据库。SQLite 的驱动库文件很小,包含完整功能的驱动可以小到只有500 KB。
SQLite是一种开源免费使用的数据库,可以从其官网下载最新版本的数据库驱动安装文件。 SQLite Expert是SQLite数据库可视化管理工具,可以从其官网下载最新的安装文件,SQLiteExpert 安装文件带有SQLite数据库驱动,所以安装SQLite Expert 后无需再下载安装SQLite数据库驱动。
主要函数:
通过设置SELECT语句查询获取数据库的内容,但是QSqlQueryModel的数据是只读的,不能进行编辑。可以用来为类(如QTableView)提供数据
QSqlQueryModel *model = new QSqlQueryModel; model->setQuery("select * from student"); //查询student表内容 model->setHeaderData(0, Qt::Horizontal, tr("id")); model->setHeaderData(1, Qt::Horizontal, tr("name")); ui->tableView->setModel(model); //将model关联到视图中 ui->tableView->show();
设置模型的查询,然后设置视图头中显示的标签。QSqlQueryModel还可以通过编程方式访问数据库,而无需将其绑定到视图:
QSqlTableModel model; model.setTable("employee"); model.select(); int salary = model.record(4).value("salary").toInt();
从employee查询SELECT *的结果集中的记录4中提取工资字段。假设工资是第2列,我们可以将最后一行重写为:
int salary = model.data(model.index(4, 2)).toInt();
默认情况下,模型是只读的。要使其可读可写,必须将其子类化并重新实现setData()和flags()。另一种选择是使用QSqlTableModel,它提供了基于单个数据库表的读写模型。
默认情况下,插入的列为空。要用数据填充它们,需要重新实现data()并分别处理任何插入的列:
QVariant MyModel::data(const QModelIndex &item, int role) const { if (item.column() == m_specialColumnNo) { // 处理列 } return QSqlQueryModel::data(item, role); }
直接设置一个数据表的名称,可以获取数据表的全部记录,其结果是可编辑的,设置为界面上的QTableView组件的数据模型后就可以显示和编辑数据。
用于从单个表读取和写入数据库记录。它构建在底层QSqlQuery之上,可以用来为类(如QTableView)提供数据。例如:
//QSqlTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase()) QSqlTableModel *model = new QSqlTableModel(parent, database); model->setTable("employee"); model->setEditStrategy(QSqlTableModel::OnManualSubmit); model->select(); model->setHeaderData(0, Qt::Horizontal, tr("Name")); model->setHeaderData(1, Qt::Horizontal, tr("Salary")); QTableView *view = new QTableView; view->setModel(model); view->hideColumn(0); // 不显示第一列 view->show();
常量 描述 QSqlTableModel::OnFieldChange 所有对模型的改变都会立即应用到数据库 QSqlTableModel::OnRowChange 对一条记录的改变会在用户选择另一条记录时被应用 QSqlTableModel::OnManualSubmit 所有的改变都会在模型中进行缓存,直到调用submitAll()或者revertAll()
QSqlRelationalTableModel
继承自QSqlTableModel
。提供了对外键的支持。一个外键就是一个表中的一个属性和其他表中的主键属性之间的一对一的映射。QSqlRelationalTableModel *model; model = new QSqlRelationalTableModel(this); //属性变化时写入数据库 model->setEditStrategy(QSqlTableModel::OnFieldChange); model->setTable("student"); //将student表的第三个属性设为course表的id属性的外键, //并将其显示为course表的name属性的值 model->setRelation(2, QSqlRelation("course","id","name")); model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID")); model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name")); model->setHeaderData(2, Qt::Horizontal, QObject::tr("Course")); model->select(); ui->tableView->setModel(model);
使用委托
Qt中还提供了一个
QSqlRelationalDelegate
委托类,它可以为QSqlRelationalTableModel
显示和编辑数据。这个委托为一个外键提供了一个QComboBox
部件来显示所有可选的数据。ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
是另外一个经常使用的类,它可以执行任何SQL语句,通过SQL语句对数据库直接进行编辑修改。QSqlQuery封装了从QSqlDatabase上执行的SQL查询中创建、导航和检索数据所涉及的功能。既可以执行SELECT、INSERT、UPDATE、DELETE等DML(数据操作语言)语句,也可以执行CREATE TABLE等DDL(数据定义语言)语句。
成功执行的SQL语句将查询的状态设置为活动,因此isActive()返回true。否则,查询的状态被设置为不活动。在这两种情况下,当执行一个新的SQL语句时,查询被定位在一个无效的记录上。在检索值之前,必须将活动查询导航到有效的记录(以便isValid()返回true)。
对于某些数据库,如果在调用commit()或rollback()时存在一个SELECT语句的活动查询,则提交或回滚将失败。
QSqlQuery query("SELECT country FROM test_table"); while (query.next()) { QString country = query.value("country").toString(); }
QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (:id, :forename, :surname)"); query.bindValue(":id", 1001); query.bindValue(":forename", "Bart"); query.bindValue(":surname", "Simpson"); query.exec(); -------------------------------------- QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (:id, :forename, :surname)"); query.bindValue(0, 1001); query.bindValue(1, "Bart"); query.bindValue(2, "Simpson"); query.exec(); ------------------------------------ QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (?, ?, ?)"); query.bindValue(0, 1001); query.bindValue(1, "Bart"); query.bindValue(2, "Simpson"); query.exec(); ----------------------------------- QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (?, ?, ?)"); query.addBindValue(1001); query.addBindValue("Bart"); query.addBindValue("Simpson"); query.exec();
private : QsqlDatabase DB;//数据库连接 QSqlTableModel* tabModel;//数据模型 QItemSelectionModel* theselection;//选择模型 QDataWidgetMapper* dataMapper;//数据映射 //打开数据库 QString aFile = QFileDialog::getOpenFileName(this, "选择数据库文件", "","SQLite数据库(*.db *.db3)") ; if (aFile.isEmpty()) { return; } DB = QSqlDatabase::addDatabase ("QSQLITE");//添加 sQLITE 数据库驱动 DB.setDatabaseName (aFile); //设置数据库名称 if( !DB.open () )//打开数据库 { QMessageBox::warning(this,"错误", "打开数据库失败", QMessageBox::OK, QMessageBox::NoButton ); return; } //打开数据表 数据库打开成功之后 tabModel = new QSqlTableModel(this,DB);//数据表 tabModel->setTable("employee") ; //设置数据表 tabModel->setSort(tabModel->fieldIndex( "EmpNo"), Qt::Ascendingorder); tabModel->setEditstrategy(QSqlTableModel::OnManualsubmit); if (!(tabModel->select()))//查询数据 ( QMessageBox::critical(this,"错误","打开数据表错误,错误信息\n" + tabModel->lastError ().text(), QMessageBox::OK, QMessageBox::NoButton) ; return; }
使用QSqIDatabase的几个函数设置数据库登录参数:
setDatabaseName() : 设置数据库名称,对于SQLite数据库,就设置为数据库文件。如果是网络型数据库,如Oracle、 SQL Server等,还需要使用setHostName()设置数据库主机名,setUserName()设置数据库用户名,setPassword()设置数据库登录密码。对于SQLite数据库,只需用setDatabaseName()设置数据库文件即可。
setSort()函数设置排序字段和排序方式,其函数原型为:
void QSqlTableModel::setSort(int column, Qt::Sortorder order) /* 第1个参数 column是排序字段的列号; 第2个参数 order是枚举类型Qt::SortOrder,表示排序方式, 取值Qt::AscendingOrder表示升序, Qt:DescendingOrder表示降序。 */
QSqlTableModel:.setEditStrategy()函数用于设置编辑策略,参数是枚举类型QSqITableMode::EditStratcgy。
QSqITableModel::OnFieldChange,字段值变化时立即更新到数据库。
QSqITableModel::OnRowChange,当前行(就是记录)变换时更新到数据库。
QSqITableModel: OnManualSubmit,所有修改暂时缓存,手动调用submitAll()保存所有修改,或调用revertAll()函数取消所有未保存修改。
QSqlRecord类记录了数据表的字段信息和一条记录的数据内容,QSqlTableModel有两个函数record()可以返回一条记录数。
QSqIRecord QSqITableModel::record(),不带参数的record()函数,返回的一个QSqIRecord对象只有记录的字段定义,但是没有数据。这个函数一般用于获取一个数据表的字段定义。
QSqlRecord QSqITableModel::record(int row),返回行号为row的记录,包括记录的字段定义和数据。
QSqIRecord 的 field()函数返回某个字段,返回数据类型是QSqIField。QSqlField封装了字段定义信息和数据。字段的定义一般在设计数据表时就固定了,不用在 QSqlRecord 里修改