原文地址:http://blog.csdn.net/NewBee520/article/details/8247236
QsqlDatabase类实现了数据库连接的操作
QsqlQuery类用来执行sql语句
QsqlRecord类封装数据库所有记录
QsqlRelationalTableModel
QsqlQueryModel
QsqlTableModel
第一:QsqlDatabase类
QsqlDatabasedb=QsqlDatabase::addDatabase("QsqlITE");采用QsqlITE数据库 db.setHostName("localhost");//设置数据库主机名 db.setDatabaseName("test");//设置数据库名 db.setUserName("root");//设置数据库登入用户名 db.setPassword("123456");//设计数据库登入密码 db.open()打开数据库连接 db.close();//释放数据库
QStringListdrivers=QsqlDatabase::drivers();//静态成员函数,是类的成员函数,不是对象的.返回所有可用的数据库驱动程序的清单 drivers.removeAll("QMysqL3");//删除列表中的项 foreach(QStringdriver,drivers)//遍历数据库驱动,测试数据库驱动种类 qDebug()<<“\t”<<driver;
第二:QsqlQuery类,查询数据库,插入值到数据库等操作数据库
QsqlQueryquery; query.prepare("INSERTINTOT_USER(name,age)VALUES(:name,:age)");query.bindValue(":name","justin");//在这定占位符上确定绑定的值 query.bindValue(":age",33); query.exec();
QsqlQueryquery;//以下执行相关sql语句 query.exec(“createtablestudent(idintprimarykey,namevarchar)”) //新建student表,id设置为主键,还有一个name项 query.exec(“insertintostudentvalues(1,’xiaogang’)”); query.exec(“insertintostudentvalues(2,’xiaoming’)”); query.exec(“insertintostudentvalues(3,’xiaohong’)”); //向表中插入3条记录 query.exec(“select*fromstudent”); 来查询出表中所有的内容。其中的sql语句“select*fromstudent”中“*”号表明查询表中记录的所有属性。而当query.exec(“select*fromstudent”);这条语句执行完后,我们便获得了相应的执行结果,因为获得的结果可能不止一条记录,所以我们称之为结果集。
seek(intn):query指向结果集的第n条记录。指定当前的位置 first():query指向结果集的第一条记录。 last():query指向结果集的最后一条记录。 next():query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录。 prevIoUs():query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录。 record():获得现在指向的记录。 value(intn):获得属性的值。其中n表示你查询的第n个属性,比方上面我们使用“select*fromstudent”就相当于“selectid,namefromstudent”,那么value(0)返回id属性的值,value(1)返回name属性的值。该函数返回QVariant类型的数据,关于该类型与其他类型的对应关系,可以在帮助中查看QVariant。 at()//返回当前查询的位置 QStringname=query.value(0).toString();//返回"name"字段的索引值"justin",value(i)返回i字段的值,0表示name,1表示age introwNum=query.at();//获取query所指向的记录在结果集中的编号 intcolumnNum=query.record().count();//获取每条记录中属性(即列)的个数 intfieldNo=query.record().indexOf(“name”);//获取”name”属性所在列的编号,列从左向右编号,最左边的编号为0 intid=query.value(0).toInt();//获取id属性的值,并转换为int型 QStringname=query.value(fieldNo).toString();//获取name属性的值 qDebug()<<“rowNumis:”<<rowNum//将结果输出 <<”idis:”<<id <<”nameis:”<<name <<”columnNumis:”<<columnNum; if(query.seek(2))//seek指定当前的位置 if(query.seek(ui->spinBox->value())) { qDebug()<<query.value(0).toInt()<<query.value(1).toString(); while(query.next())//每执行一次该函数,便指向相邻的下一条记录。 { qDebug()<<query.value(0).toInt()<<query.value(1).toString(); //value(i)返回i字段的值,0表示id,1表示name } }
//批处理操作函数--批量插入到数据库中 QsqlQueryq; q.prepare(“insertintostudentvalues(?,?)”); QVariantListints;//QVariantList==QList<QVariant> ints<<10<<11<<12<<13; q.addBindValue(ints);//绑定 QVariantListnames; names<<“xiaoming”<<“xiaoliang”<<“xiaogang”<<QVariant(QVariant::String //最后一个是空字符串,应与前面的格式相同 q.addBindValue(names); if(!q.execBatch())//进行批处理,如果出错就输出错误 qDebug()<<q.lastError();第三:QsqlQueryModel类只读数据模型为数据库结果集
1.QsqlQueryModel*model=newQsqlQueryModel; model->setQuery("select*fromstudent"); model->setHeaderData(0,Qt::Horizontal,tr("id")); model->setHeaderData(1,tr("name")); QTableView*view=newQTableView; view->setModel(model);//重新定义模型,model直接从database.db的数据库中插入数据view->show(); 2.intcolumn=model->columnCount();//获得列数 introw=model->rowCount();//获得行数 QsqlRecordrecord=model->record(1);//获得一条记录 QModelIndexindex=model->index(1,1);//获得一条记录的一个属性的值 qDebug()<<"columnnumis:"<<column<<endl <<"rownumis:"<<row<<endl <<"thesecondrecordis:"<<record<<endl <<"thedataofindex(1,1)is:"<<index.data(); 3.QsqlQueryquery=model->query();//返回与QsqlQuery相关的模型 query.exec("insertintostudentvalues(10,'yafei10')");//在模型中插入一条记录 model->setQuery("select*fromstudent");//再次查询整张表 view->show();//再次进行显示,这句也可以不写 4.使QsqlQueryModel类创建的数据库能读写,继承QAbstractItemModel类 刚开始我们就讲到,这个模型默认是只读的,所以我们在窗口上并不能对表格中的内容进行修改。但是我们可以创建自己的模型,然后按照我们自己的意愿来显示数据和修改数据。 要想使其可读写,需要自己的类继承自QsqlQueryModel,并且重写setData()和flags()两个函数。如果我们要改变数据的显示,就要重写data()函数。 boolQAbstractItemModel::setData(constQModelIndex&index,constQVariant&value,introle=Qt::EditRole)//设置根据index索引到的value值 Qt::ItemFlagsQAbstractItemModel::flags(constQModelIndex&index)const//返回给定的index索引的标志 QVariantQAbstractItemModel::data(constQModelIndex&index,introle=Qt::DisplayRole)const//返回index和role(显示状态)确定的值 Qt::ItemFlagsMysqLQueryModel::flags(constQModelIndex&index)const { //返回表格是否可更改的标志 Qt::ItemFlagsflags=QsqlQueryModel::flags(index); if(index.column()==1)//第二个属性可更改 flags|=Qt::ItemIsEditable;//flags能被编辑,所以第二列能被编辑 returnflags; } QVariantMysqLQueryModel::data(constQModelIndex&index,introle)const { //更改数据显示样式 QVariantvalue=QsqlQueryModel::data(index,role); if(role==Qt::TextColorRole&&index.column()==0) //Qt::TextColorRole是确定颜色等为9,所以与之后是第一列 returnqVariantFromValue(QColor(Qt::red));//第一个属性的字体颜色为红色 returnvalue; }
第四:QsqlTableModel继承QsqlQueryModel类--该类提供了一个可读写单张sql表的可编辑数据模型,功能:修改,插入,删除,查询,和排序
1.//在tableview表格中显示数据库数据 model=newQsqlTableModel(this); model->setTable("student");//设置"student"的数据库表格 model->setEditStrategy(QsqlTableModel::OnManualSubmit);//设置保存策略为手动提交 model->select();//选取整个表的所有行 //model->removeColumn(1);//不显示name属性列,如果这时添加记录,则该属性的值添加不上。 ui->tableView->setModel(model);//重新定义模型,model直接从database.db的数据库中插入数据 //ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//使其不可编辑 2.//当tableview被修改后,要通过submitAll()函数进行保存boolQsqlTableModel::submitAll(),提交所有被修改的数据,然后修改的数据被保存在数据库中 model->database().transaction();//开始事务操作 if(model->submitAll()) {//提交所有被修改的数据,然后修改的数据被保存在数据库中 model->database().commit();//提交 } else{ model->database().rollback();//回滚 QMessageBox::warning(this,tr(“tableModel”),tr(“数据库错误:%1″) .arg(model->lastError().text())); } model->revertAll();//撤销修改 3.查询操作--voidQsqlTableModel::setFilter(constQString&filter)//筛选 QStringname=ui->lineEdit->text(); model->setFilter(QObject::tr(“name=‘%1′”).arg(name));//根据姓名进行筛选 model->select();//显示结果 4.排序操作 model->setSort(0,Qt::AscendingOrder);//id属性,即第0列,升序排列 model->select(); model->setSort(0,Qt::DescendingOrder); model->select(); 5.删除行 //intcurRow=ui->tableView->currentIndex().row();//获取选中的行 //model->removeRow(curRow);//删除一行//删除该行 QItemSelectionModel*selections=ui->tableView->selectionModel(); //返回当前的选择模式 QModelIndexListselected=selections->selectedIndexes(); //返回所有选定模型项目索引列表 foreach(QModelIndexindex,selected) { intcurRow=index.row(); model->removeRow(curRow);//删除所有被选中的行 } intok=QMessageBox::warning(this,tr("删除当前行!"),tr("你确定""删除当前行吗") QMessageBox::Yes,QMessageBox::No); if(ok==QMessageBox::No) { model->revertAll();//如果不删除,则撤销 } elsemodel->submitAll();//否则提交,在数据库中删除该行 6.插入操作//插入行 introwNum=model->rowCount();//获得表的行数 intid=10; model->insertRow(rowNum);//添加一行 model->setData(model->index(rowNum,0),id);//给新行添加id属性值 //model->submitAll();//可以直接提交 QsqlRelationalTableModel->Inherits QsqlTableModel->Inherits QsqlQueryModel->Inherits QAbstractTableModel->Inherits QAbstractItemModel->Inherits
第五:QsqlRelationalTableModel--该类为单张的数据库表提供了一个可编辑的数据模型,它支持外键,除此之外和QsqlTableModel没有什么不同
model->setRelation(2,QsqlRelation(“course”,”id”,”name”));//设置外键 //将student表的第三个属性设为course表的id属性的外键,并将其显示为course表的name属性的值(course表在id上显示为name属性值) 如果用户更改课程属性,那么他只能在课程表中有的课程中进行选择,而不能随意填写课程。在Qt中的QsqlRelationalDelegate委托类就能实现这个功能 ui->tableView->setItemDelegate(newQsqlRelationalDelegate(ui->tableView)); QsqlRelationalDelegate类--提供委托delegate用来显示编辑QsqlRelationalTableModel类 QTableView*view=newQTableView; view->setModel(model); view->setItemDelegate(newQsqlRelationalDelegate(view)); QDataWidgetMapper类可以将数据库和控件(如QLineEdit)连接起来,使控件得到数据库的值(例子:editEmployees)