原文地址:http://blog.csdn.net/NewBee520/article/details/8247236
http://www.voidcn.com/blog/G1036583997/article/p-4981860.html
QSqlDatabase类实现了数据库连接的操作
QSqlQuery类用来执行SQL语句
QSqlRecord类封装数据库所有记录
QSqlRelationalTableModel
QSqlQueryModel
QSqlTableModel
第一:QSqlDatabase类
1 2 3 4 5 6 7 |
QSqlDatabase db = QSqlDatabase::addDatabase(<span class="hljs-string">"QSQLITE"</span>); 采用QSQLITE数据库 db.setHostName(<span class="hljs-string">"localhost"</span>); <span class="hljs-comment">//设置数据库主机名 </span> db.setDatabaseName(<span class="hljs-string">"test"</span>); <span class="hljs-comment">//设置数据库名 </span> db.setUserName(<span class="hljs-string">"root"</span>); <span class="hljs-comment">//设置数据库登入用户名 </span> db.setPassword(<span class="hljs-string">"123456"</span>); <span class="hljs-comment">//设计数据库登入密码 </span> db.open()打开数据库连接 db.close();<span class="hljs-comment">//释放数据库</span> |
1 2 3 4 |
QStringList drivers = QSqlDatabase::drivers();<span class="hljs-comment">//静态成员函数,是类的成员函数,不是对象的.返回所有可用的数据库驱动程序的清单</span> drivers.removeAll(<span class="hljs-string">"QMYSQL3"</span>); <span class="hljs-comment">//删除列表中的项</span> foreach(QString driver, drivers) <span class="hljs-comment">//遍历数据库驱动 ,测试数据库驱动种类</span> qDebug() << “\t” << driver; |
第二:QSqlQuery类,查询数据库,插入值到数据库等操作数据库
1 2 3 4 |
QSqlQuery query; query.prepare("<span class="hljs-operator"><span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> T_USER (name, age) <span class="hljs-keyword">VALUES</span> (:name, :age)<span class="hljs-string">"); query.bindValue("</span>:name<span class="hljs-string">", "</span>justin<span class="hljs-string">"); //在这定占位符上确定绑定的值 query.bindValue("</span>:age<span class="hljs-string">", 33); query.exec(); </span></span> |
1 2 3 4 5 6 7 8 9 |
QSqlQuery query; //以下执行相关SQL语句 query.exec(“<span class="hljs-operator"><span class="hljs-keyword">create</span> <span class="hljs-keyword">table</span> student(id <span class="hljs-built_in">int</span> <span class="hljs-keyword">primary</span> <span class="hljs-keyword">key</span>,name <span class="hljs-built_in">varchar</span>)”) //新建student表,id设置为主键,还有一个name项 <span class="hljs-keyword">query</span>.<span class="hljs-keyword">exec</span>(“<span class="hljs-keyword">insert</span> <span class="hljs-keyword">into</span> student <span class="hljs-keyword">values</span>(<span class="hljs-number">1</span>,’xiaogang’)”);</span> query.exec(“<span class="hljs-operator"><span class="hljs-keyword">insert</span> <span class="hljs-keyword">into</span> student <span class="hljs-keyword">values</span>(<span class="hljs-number">2</span>,’xiaoming’)”);</span> query.exec(“<span class="hljs-operator"><span class="hljs-keyword">insert</span> <span class="hljs-keyword">into</span> student <span class="hljs-keyword">values</span>(<span class="hljs-number">3</span>,’xiaohong’)”);</span> //向表中插入3条记录 query.exec(“<span class="hljs-operator"><span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> student”);</span> 来查询出表中所有的内容。其中的SQL语句“<span class="hljs-operator"><span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> student”中“*”号表明查询表中记录的所有属性。而当<span class="hljs-keyword">query</span>.<span class="hljs-keyword">exec</span>(“<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> student”);</span>这条语句执行完后,我们便获得了相应的执行结果,因为获得的结果可能不止一条记录,所以我们称之为结果集。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
seek(<span class="hljs-keyword">int</span> n) :query指向结果集的第n条记录。指定当前的位置 first() :query指向结果集的第一条记录。 last() :query指向结果集的最后一条记录。 next() :query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录。 previous() :query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录。 record() :获得现在指向的记录。 <span class="hljs-keyword">value</span>(<span class="hljs-keyword">int</span> n) :获得属性的值。其中n表示你查询的第n个属性,比方上面我们使用“<span class="hljs-keyword">select</span> * <span class="hljs-keyword">from</span> student”就相当于“<span class="hljs-keyword">select</span> id, name <span class="hljs-keyword">from</span> student”,那么<span class="hljs-keyword">value</span>(<span class="hljs-number">0</span>)返回id属性的值,<span class="hljs-keyword">value</span>(<span class="hljs-number">1</span>)返回name属性的值。该函数返回QVariant类型的数据,关于该类型与其他类型的对应关系,可以在帮助中查看QVariant。 at()<span class="hljs-comment">//返回当前查询的位置</span> QString name = query.<span class="hljs-keyword">value</span>(<span class="hljs-number">0</span>).toString(); <span class="hljs-comment">//返回"name"字段的索引值"justin",value(i)返回i字段的值,0表示name,1表示age</span> <span class="hljs-keyword">int</span> rowNum = query.at();<span class="hljs-comment">//获取query所指向的记录在结果集中的编号</span> <span class="hljs-keyword">int</span> columnNum = query.record().count();<span class="hljs-comment">//获取每条记录中属性(即列)的个数</span> <span class="hljs-keyword">int</span> fieldNo = query.record().indexOf(“name”);<span class="hljs-comment">//获取”name”属性所在列的编号,列从左向右编号,最左边的编号为0</span> <span class="hljs-keyword">int</span> id = query.<span class="hljs-keyword">value</span>(<span class="hljs-number">0</span>).toInt();<span class="hljs-comment">//获取id属性的值,并转换为int型</span> QString name = query.<span class="hljs-keyword">value</span>(fieldNo).toString();<span class="hljs-comment">//获取name属性的值</span> qDebug() << “rowNum <span class="hljs-keyword">is</span> : ” << rowNum <span class="hljs-comment">//将结果输出</span> << ” id <span class="hljs-keyword">is</span> : ” << id << ” name <span class="hljs-keyword">is</span> : ” << name << ” columnNum <span class="hljs-keyword">is</span> : ” << columnNum; <span class="hljs-keyword">if</span>(query.seek(<span class="hljs-number">2</span>)) <span class="hljs-comment">//seek指定当前的位置</span> <span class="hljs-keyword">if</span>(query.seek(ui->spinBox-><span class="hljs-keyword">value</span>())) { qDebug() << query.<span class="hljs-keyword">value</span>(<span class="hljs-number">0</span>).toInt() << query.<span class="hljs-keyword">value</span>(<span class="hljs-number">1</span>).toString(); <span class="hljs-keyword">while</span>(query.next()) <span class="hljs-comment">//每执行一次该函数,便指向相邻的下一条记录。</span> { qDebug() << query.<span class="hljs-keyword">value</span>(<span class="hljs-number">0</span>).toInt() << query.<span class="hljs-keyword">value</span>(<span class="hljs-number">1</span>).toString(); <span class="hljs-comment">//value(i)返回i字段的值,0表示id,1表示name</span> } } |
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="hljs-comment">//批处理操作函数--批量插入到数据库中</span> QSqlQuery q; q.prepare(“<span class="hljs-function">insert into student <span class="hljs-title">values</span> <span class="hljs-params">(?, ?)</span>”)</span>; QVariantList ints; <span class="hljs-comment">//QVariantList==QList<QVariant></span> ints << <span class="hljs-number">10</span> << <span class="hljs-number">11</span> << <span class="hljs-number">12</span> << <span class="hljs-number">13</span>; q.addBindValue(ints); <span class="hljs-comment">//绑定</span> QVariantList names; names<<“xiaoming” << “xiaoliang” << “xiaogang” << QVariant(QVariant::String <span class="hljs-comment">//最后一个是空字符串,应与前面的格式相同</span> q.addBindValue(names); <span class="hljs-keyword">if</span> (!q.execBatch()) <span class="hljs-comment">//进行批处理,如果出错就输出错误</span> qDebug() << q.lastError();第三:QSqlQueryModel类 只读数据模型为数据库结果集 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<span class="hljs-number">1.</span>QSqlQueryModel *model = <span class="hljs-keyword">new</span> QSqlQueryModel; model->setQuery(<span class="hljs-string">"select * from student"</span>); model->setHeaderData(<span class="hljs-number">0</span>, Qt::Horizontal, tr(<span class="hljs-string">"id"</span>)); model->setHeaderData(<span class="hljs-number">1</span>, Qt::Horizontal, tr(<span class="hljs-string">"name"</span>)); QTableView *view = <span class="hljs-keyword">new</span> QTableView; view->setModel(model);<span class="hljs-comment">//重新定义模型,model直接从database.db的数据库中插入数据view->show();</span> <span class="hljs-number">2.</span><span class="hljs-keyword">int</span> column = model->columnCount(); <span class="hljs-comment">//获得列数</span> <span class="hljs-keyword">int</span> row = model->rowCount(); <span class="hljs-comment">// 获得行数</span> QSqlRecord record = model->record(<span class="hljs-number">1</span>); <span class="hljs-comment">//获得一条记录</span> QModelIndex index = model->index(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>); <span class="hljs-comment">//获得一条记录的一个属性的值</span> qDebug() << <span class="hljs-string">"column num is:"</span> << column << endl << <span class="hljs-string">"row num is:"</span> << row << endl <<<span class="hljs-string">"the second record is:"</span> << record << endl <<<span class="hljs-string">"the data of index(1,1) is:"</span> << index.data(); <span class="hljs-number">3.</span>QSqlQuery query = model->query(); <span class="hljs-comment">//返回与QSqlQuery相关的模型</span> query.exec(<span class="hljs-string">"insert into student values (10,'yafei10')"</span>);<span class="hljs-comment">//在模型中插入一条记录</span> model->setQuery(<span class="hljs-string">"select * from student"</span>); <span class="hljs-comment">//再次查询整张表</span> view->show(); <span class="hljs-comment">//再次进行显示,这句也可以不写</span> <span class="hljs-number">4.</span> 使QSqlQueryModel类 创建的数据库能读写,继承QAbstractItemModel类 刚开始我们就讲到,这个模型默认是只读的,所以我们在窗口上并不能对表格中的内容进行修改。但是我们可以创建自己的模型,然后按照我们自己的意愿来显示数据和修改数据。 要想使其可读写,需要自己的类继承自QSqlQueryModel,并且重写setData() 和 flags() 两个函数。如果我们要改变数据的显示,就要重写data() 函数。 <span class="hljs-keyword">bool</span> QAbstractItemModel::setData ( <span class="hljs-keyword">const</span> QModelIndex & index, <span class="hljs-keyword">const</span> QVariant & value, <span class="hljs-keyword">int</span> role = Qt::EditRole ) <span class="hljs-comment">//设置根据index索引到的value值</span> Qt::ItemFlags QAbstractItemModel::flags ( <span class="hljs-keyword">const</span> QModelIndex & index ) <span class="hljs-keyword">const</span> <span class="hljs-comment">//返回给定的index索引的标志</span> QVariant QAbstractItemModel::data ( <span class="hljs-keyword">const</span> QModelIndex & index, <span class="hljs-keyword">int</span> role = Qt::DisplayRole ) <span class="hljs-keyword">const</span> <span class="hljs-comment">//返回index和role(显示状态)确定的值</span> Qt::ItemFlags MySqlQueryModel::flags(<span class="hljs-keyword">const</span> QModelIndex &index) <span class="hljs-keyword">const</span> { <span class="hljs-comment">//返回表格是否可更改的标志</span> Qt::ItemFlags flags = QSqlQueryModel::flags(index); <span class="hljs-keyword">if</span> (index.column() == <span class="hljs-number">1</span>) <span class="hljs-comment">//第二个属性可更改</span> flags |= Qt::ItemIsEditable; <span class="hljs-comment">//flags能被编辑,所以第二列能被编辑</span> <span class="hljs-keyword">return</span> flags; } QVariant MySqlQueryModel::data(<span class="hljs-keyword">const</span> QModelIndex &index, <span class="hljs-keyword">int</span> role) <span class="hljs-keyword">const</span> { <span class="hljs-comment">//更改数据显示样式</span> QVariant value = QSqlQueryModel::data(index, role); <span class="hljs-keyword">if</span> (role == Qt::TextColorRole && index.column() == <span class="hljs-number">0</span>) <span class="hljs-comment">//Qt::TextColorRole是确定颜色等为9,所以与之后是第一列</span> <span class="hljs-keyword">return</span> qVariantFromValue(QColor(Qt::red)); <span class="hljs-comment">//第一个属性的字体颜色为红色</span> <span class="hljs-keyword">return</span> value; } |
第四:QSqlTableModel 继承QSqlQueryModel类 –该类提供了一个可读写单张SQL表的可编辑数据模型,功能:修改,插入,删除,查询,和排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<span class="hljs-number">1.</span> <span class="hljs-comment">//在tableview表格中显示数据库数据</span> model = <span class="hljs-keyword">new</span> QSqlTableModel(this); model->setTable(<span class="hljs-string">"student"</span>); <span class="hljs-comment">//设置"student"的数据库表格</span> model->setEditStrategy(QSqlTableModel::OnManualSubmit);<span class="hljs-comment">//设置保存策略为手动提交</span> model->select(); <span class="hljs-comment">//选取整个表的所有行</span> <span class="hljs-comment">//model->removeColumn(1); //不显示name属性列,如果这时添加记录,则该属性的值添加不上。</span> ui->tableView->setModel(model); <span class="hljs-comment">//重新定义模型,model直接从database.db的数据库中插入数据</span> <span class="hljs-comment">//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//使其不可编辑</span> <span class="hljs-number">2.</span><span class="hljs-comment">//当tableview被修改后,要通过submitAll()函数进行保存 bool QSqlTableModel::submitAll (),提交所有被修改的数据,然后修改的数据被保存在数据库中</span> model->database().transaction(); <span class="hljs-comment">//开始事务操作</span> <span class="hljs-keyword">if</span> (model->submitAll()) { <span class="hljs-comment">//提交所有被修改的数据,然后修改的数据被保存在数据库中</span> model->database().commit(); <span class="hljs-comment">//提交</span> } <span class="hljs-keyword">else</span> { model->database().rollback(); <span class="hljs-comment">//回滚</span> QMessageBox::warning(this, tr(“tableModel”),tr(“数据库错误: %<span class="hljs-number">1</span>″) .arg(model->lastError().text())); } model->revertAll(); <span class="hljs-comment">//撤销修改</span> <span class="hljs-number">3.</span> 查询操作--void QSqlTableModel::setFilter ( <span class="hljs-keyword">const</span> QString & filter ) <span class="hljs-comment">//筛选</span> QString name = ui->lineEdit->text(); model->setFilter(QObject::tr(“name = ‘%<span class="hljs-number">1</span>′”).arg(name)); <span class="hljs-comment">//根据姓名进行筛选</span> model->select(); <span class="hljs-comment">//显示结果</span> <span class="hljs-number">4.</span>排序操作 model->setSort(<span class="hljs-number">0</span>,Qt::AscendingOrder); <span class="hljs-comment">//id属性,即第0列,升序排列</span> model->select(); model->setSort(<span class="hljs-number">0</span>,Qt::DescendingOrder); model->select(); <span class="hljs-number">5.</span>删除行 <span class="hljs-comment">// int curRow = ui->tableView->currentIndex().row();//获取选中的行</span> <span class="hljs-comment">// model->removeRow(curRow); //删除一行//删除该行</span> QItemSelectionModel *selections = ui->tableView->selectionModel(); <span class="hljs-comment">//返回当前的选择模式</span> QModelIndexList selected = selections->selectedIndexes(); <span class="hljs-comment">//返回所有选定模型项目索引列表</span> <span class="hljs-keyword">foreach</span> (QModelIndex index, selected) { int curRow=index.row(); model->removeRow(curRow); <span class="hljs-comment">//删除所有被选中的行</span> } int ok = QMessageBox::warning(this,tr(<span class="hljs-string">"删除当前行!"</span>),tr(<span class="hljs-string">"你确定"</span><span class="hljs-string">"删除当前行吗"</span>) QMessageBox::Yes,QMessageBox::No); <span class="hljs-keyword">if</span>(ok == QMessageBox::No) { model->revertAll(); <span class="hljs-comment">//如果不删除,则撤销</span> } <span class="hljs-keyword">else</span> model->submitAll(); <span class="hljs-comment">//否则提交,在数据库中删除该行</span> <span class="hljs-number">6.</span>插入操作<span class="hljs-comment">//插入行</span> int rowNum = model->rowCount(); <span class="hljs-comment">//获得表的行数</span> int id = <span class="hljs-number">10</span>; model->insertRow(rowNum); <span class="hljs-comment">//添加一行</span> model->setData(model->index(rowNum,<span class="hljs-number">0</span>),id); <span class="hljs-comment">//给新行添加id属性值</span> <span class="hljs-comment">//model->submitAll(); //可以直接提交</span> QSqlRelationalTableModel->Inherits QSqlTableModel->Inherits QSqlQueryModel->Inherits QAbstractTableModel->Inherits QAbstractItemModel->Inherits |
第五:QSqlRelationalTableModel–该类为单张的数据库表提供了一个可编辑的数据模型,它支持外键,除此之外和QSqlTableModel没有什么不同
1 2 3 4 5 6 7 8 9 |
model->setRelation(<span class="hljs-number">2</span>,QSqlRelation(“course”,”id”,”name”)); <span class="hljs-comment">//设置外键</span> <span class="hljs-comment">//将student表的第三个属性设为course表的id属性的外键,并将其显示为course表的name属性的值(course表在id上显示为name属性值)</span> 如果用户更改课程属性,那么他只能在课程表中有的课程中进行选择,而不能随意填写课程。在Qt中的QSqlRelationalDelegate委托类就能实现这个功能 ui->tableView->setItemDelegate(<span class="hljs-keyword">new</span> QSqlRelationalDelegate(ui->tableView)); QSqlRelationalDelegate类--提供委托delegate用来显示编辑QSqlRelationalTableModel类 QTableView *view = <span class="hljs-keyword">new</span> QTableView; view->setModel(model); view->setItemDelegate(<span class="hljs-keyword">new</span> QSqlRelationalDelegate(view)); QDataWidgetMapper类可以将数据库和控件(如QLineEdit)连接起来,使控件得到数据库的值(例子:editEmployees) |