Qt提供了QtSql模块来进行独立于平台的数据库操作,这里的“平台”既包括操作系统平台,也包括各个数据库平台。Qt使用一个QDatabase表示一个数据库连接,在底层,Qt使用不同的驱动程序来与不同的数据库API进行交互。
通常,Qt只默认搭载了QSqlLite驱动程序,如果需要使用其他数据库,需要下载相应的数据库,将其驱动程序加载到Qt中。例如需要载入Mysql,在Mysql的安装目录下找到 libmysql.dll,将其复制到QT安装目录下的mingw x_x_xx文件夹的bin目录下,如 “D:\Qt\5.9.9\mingw53_32\bin”。
Qt中使用数据库首先要在.pro文件中添加sql模块
QT += core gui sql
然后定义QSqlDatabase变量表示数据库连接
QSqlDatabase databaselink;
在连接数据库之前可以使用QSqlDatabase::drivers()
查看本机Qt已经支持的数据库驱动
qDebug()<<"支持的数据库驱动: "<<QSqlDatabase::drivers();
以上输出就是本机Qt已经载入的数据库驱动
连接mysql数据库,首先使用QSqlDatabase::addDatabase()
选择将要连接的数据库驱动,使用databaselink.setxxxx()
方法设置相应数据库的地址、用户名、密码、连接的数据库名称等信息
databaselink = QSqlDatabase::addDatabase("QMYSQL");
databaselink.setHostName("127.0.0.1");
databaselink.setUserName("root");
databaselink.setPassword("root");
databaselink.setDatabaseName("mfcchat");
if(!databaselink.open()){
qDebug()<<"数据库连接失败!";
}else
{
qDebug()<<"数据库连接成功!";
}
通过databaselink.open()
可以判断是否可以正常打开、使用数据库
数据库的操作主要使用QSqlQuery实例来完成,已创建一张数据表为例
QSqlQuery query;
QString createtabelsql = "create table test(id int primary key auto_increment,name varchar(255),age int)";
if(query.exec(createtabelsql)){
qDebug()<<"数据表创建成功";
}else{
qDebug()<<"数据表创建失败! "<<query.lastError().text();
}
其中query.lastError.text()
可以查看该QSqlQuery实例执行的错误情况,增删改查等数据库操作都可以使用QSqlQuery实例exec()
方法执行相应的sql语句完成
数据库的批量操作是为了提高插入大量数据而进行的一种操作,数据库的批量操作常见的分为两种风格ODBC风格
和Orcal风格
,数据库批量操作分为三个步骤prepare()
(预处理)、绑定数据
、execBatch()
(执行)
所谓的ODBC风格
就是在数据库批量操作预处理处理的时候使用?
作为通配符进行数据绑定,具体示例如下
QSqlQuery query;
query.prepare("insert into test(name,age) values(?,?)");//prepare()
QStringList namelist;
namelist<<"zhangsan"<<"Lisi"<<"Wangwu";
query.addBindValue(namelist);//绑定数据
QVariantList agelist;
agelist<<18<<20<<22;
query.addBindValue(agelist);//绑定数据
if(!query.execBatch()){
qDebug()<<"数据插入失败!"<<query.lastError().text();
}else{
qDebug()<<"数据插入成功!";
}
可以看到刷新数据库以后可以看到刚刚插入的数据,因为主键自增所以刚刚没有设置主键字段的数据
所谓的Orcal风格
就是使用:自定义名字
作为通配符进行数据绑定,具体示例如下
QSqlQuery query;
query.prepare("insert into test(name,age) values(:nameL,:ageL)");
QStringList namelist;
namelist<<"Tt"<<"Pp"<<"Kk";
query.bindValue(":nameL",namelist);
QVariantList agelist;
agelist<<40<<50<<60;
query.bindValue(":ageL",agelist);
if(!query.execBatch()){
qDebug()<<"数据插入失败: "<<query.lastError().text();
}else{
qDebug()<<"数据插入成功!";
}
刷新之后可以看到数据也插入成功,相比之下两种风格的差别在于通配符以及数据的绑定。但是,有幸在另一本书里看到过一种类似于上诉两种风格混搭的写法
QSqlQuery query;
query.prepare("insert into test(name,age) values(:name,:age)");
QStringList namelist;
namelist<<"SS"<<"ZZ";
query.addBindValue(namelist);
QVariantList agelist;
agelist<<100<<200;
query.addBindValue(agelist);
if(!query.execBatch()){
qDebug()<<"数据插入失败: "<<query.lastError().text();
}else{
qDebug()<<"数据插入成功!";
}
数据库刷新之后数据依然添加成功,所以ODBC风格
和Orcal风格
的差别只在于通配符的不同,但是更推荐使用Orcal风格
,因为数据绑定的两种方法都适用,更加便捷。
Qt除了提供QSqlQuery
实例对数据库通过exec()
执行sql语句进行操作之外,还提供基于QSqlTableModel
的模型处理方式,QSqlTableModel
与tableView
结合使用(model/view),新建一个界面如下
其中空白的为tableview。
新建QSqlTableModel
实例
QSqlTableModel *model;
数据库连接成功后为该实例指定数据表、设置编辑策略等
model = new QSqlTableModel(this);
model->setTable("test");//指定数据表为test
model->select();
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置编辑策略为手动提交
ui->tableView->setModel(model);//设置tableview的model
运行程序之后即可在tableview中查看到数据库中的数据,此时tableview中的数据是可以修改的,但修改之后不会提交到数据库(即不会修改数据库的数据),因为设置的编辑策略为手动提交
Tips: QSqlTableModel实例不能实现复杂查询,select()部分的内容不可以设置,默认 select * from table
QSqlTableModel
查找数据与sql语句不同,使用的是setFilter()
方法对数据进行过滤,实例如下
void MainWindow::on_selectitem_clicked()
{
QString name = ui->lineEdit->text();
model->setFilter(QString("name = '%1'").arg(name));
model->select();
}
使用model->insertRow()
方法插入新行(整行插入),填写数据后通过事务提交(commit)
新增数据到数据库,示例如下
void MainWindow::on_updateitem_clicked()
{
model->database().transaction();//开始事务
if(!model->submitAll()){
model->database().rollback();
qDebug()<<"添加行出错 "<<model->lastError().text();
}else{
model->database().commit();
qDebug()<<"添加行成功! ";
}
}
void MainWindow::on_additem_clicked()
{
int rownum = model->rowCount();
model->insertRow(rownum);
}
添加新行之后在tableview中填写新行的数据(可以同时修改其他行的数据),然后点击"更改"通过事务transcation()
将model的全部修改(model->commitall()
)提交到数据库,为什么使用事务,因为提交的过程中可能只会成功一部分,为了维护数据的一致性,使用事务(要么全部修改,要么都不修改)
当然也可以只是单独添加一行,示例如下
void MainWindow::on_additem_clicked()
{
int rownum = model->rowCount();
model->insertRow(rownum);
model->setData(model->index(rownum,1),"danhang");
model->setData(model->index(rownum,2),9999);
model->submitAll();
}
该方法较上诉方法的区别在于新增行数据的设置
数据修改和插入数据一样,可以使用setData()
方法修改之后使用model->submitAll()
方法单独提交一行,也可以在tableview里修改后使用事务的方式批量提交
int rownum = model->rowCount();
model->setData(model->index(rownum-1,1),"ABCDE");
model->setData(model->index(rownum-1,2),89);
model->submitAll();
上述代码实现的就是修改最后一行的数据
model->database().transaction();//开始事务
if(!model->submitAll()){
model->database().rollback();
qDebug()<<"添加行出错 "<<model->lastError().text();
}else{
model->database().commit();
qDebug()<<"添加行成功! ";
}
在tableview里修改数据后,可以使用上述代码批量修改到数据库
QSqlTableModel
删除数据主要使用removeRow()
和removeRows()
,前者单独删除一行,后者删除多行
void MainWindow::on_deleteitem_clicked()
{
int num = ui->tableView->currentIndex().row();
model->removeRow(num);
int ok = QMessageBox::warning(this,"Warning","确认删除此行?",QMessageBox::Yes,QMessageBox::No);
if(ok == QMessageBox::Yes){
model->submitAll();
}else{
model->revertAll();
}
}
上述代码实现的功能即为删除所选行。
Qt操作Mysql数据库就简单的介绍到这里了,如有错误,敬请指正!