qt如何创建数据库表和表头,qt中用setmodel查询数据库

Qt提供了与数据库联动以开发应用程序的模块。与其他API相比,Qt提供的API更直观,也更容易理解。使用Qt提供的API之前,需要添加如下的头文件。

#include <QtSql>

为使用Qt开发应用程序,与使用C++语言类似,数据库使用SQL语言查询数据。SQL是以特定形式收集、积累、保存数据的数据文件,并从逻辑上查询记录,以准确检测相关信息。

Qt提供的数据库类

数据库类 说明

QSql 使用Qt提供的SQL库的类

QSqlDriverCreatorBase SQL驱动的父类

QSqlDriverCreator 用于指定驱动类型的模板库

QSqlDatabase 用于连接数据库的类

QSqlDriver 用于访问特定SQL数据库的抽象类

QSqlError 告知数据库发生的错误信息的类

QSqlField SQL数据库表格和视图中调整字段的类

QSqlIndex 运行数据库索引的类

QSqlQuery 用于运行SQL语句的类

QSqlRecord 隐藏数据库记录的类

QSqlResult 为访问特定数据库的数据而抽象化的接口类

QSqlQueryModel 为SQL结果和数据模型而仅支持只读模式的类

QSqlRelationalTableModel 使用外键在单一数据表修改数据类型的类

QSqlTableModel 在单一数据库表修改数据模型的类

Qt提供的数据库层可分为如下3种形式:

驱动层(Driver Layer):驱动层是连接SQL API和数据库的层。比如:QSQLDriver、QSqlDriverCreator、QSqlDriverPlugin、QSqlDriverResult等;

SQL API层:SQL QPI层时SQL驱动的父类,是访问数据库进行数据操作的层。比如:QSqlDatabase、QSqlQuery等;

用户界面层(User Interface Layer):改成用于连接数据库保存的数据和控件,以提供用户界面。比如:QSqlQueryModel、QSqlTableModel、QSqlRealtionalTableModel等。

关联和支持数据库的驱动

为访问数据库,Qt使用QSqlQuery和QSqlQueryModel类关联特定数据库,并生成列表或操作记录。QSqlDatabase可使用数据库固有用户账号进行关联,同时也可以访问不使用用户账号的数据库。

QSqlDatabase db=QSqlDatabase::addDatabase(“QMYSQL”); //生成数据库关联对象,附上数据库驱动名

db.setHostName(“bigblue”); //访问远程或本地数据库

db.setDatabaseName(“flightdb”);

db.setUserName(“acarlson”);

db.setPassword(“1uTbSbAs”);

bool ok=db.open(); //使用open()函数,关联数据库

Qt需要驱动以关联数据库,并支持如下数据库:

Qt支持的数据库

驱动名 DBMS

QDB2 IBM DB2(7.1及以上版本)

QIBASE Borland InterBase

QMYSQL MySQL

QOCI Oracle调用接口驱动

QODBC Microsoft SQL Server和其他ODBC

QPSQL PostgreSQL(7.2及以上版本)

QSQLITE2 SQLite version 2

QSQLITE SQLite version 3

QTDS Sybase Asaptive Sever

SQLite是在进程内运行的轻量级数据库,支持所有操作系统平台。在Windows和Linux平台上,可以使用OCI、Oracle、PostgreSQL和MySQL等。

Qt为了关联特定的数据库系统,可以将必须的驱动创建为插件形式,此时需要数据库系统提供的客户端库。

创建Qt配置脚本时,必须标明Linux和Mac OS X平台,以查找客户端库。可参考配置脚本的详细帮助-help选项。

配置脚本无法查找需要的数据库的库和头文件。因此,必须使用数据库客户端-L和头文件-I选项进行指定。Qt常用-qt-sql-<driver>创建数据库驱动,使用-plugin-sql-<driver>创建插件形式的驱动。

使用SQL语句的数据库查询

QSqlQuery类使用SQL语句查询数据库。创建QSqlQuery对象并使用QSqlQuery类的函数exec(),即可执行SQL语句。

QSqlQuery query;

query.exec(“SELECT * from employee”);

使用结果集(result set)查询数据库

QSqlQuery类支持访问记录的结果集的方法。调用该类提供的函数exec(),QSqlQuery类的指针位于第一个记录指针之前。因此,必须使用函数next()移动指针,使其指向第一个记录。要访问其他记录,则可如下所示,循环使用函数next():

QSqlQuery query;

query.exec(“SELECT * from employee”);

while(query.next()){

QString name=query.value(0).toString();

int salary=query.value(1).toInt();

qDebug()<<name<<salary;

}

QSqlQuery类的成员函数value()从当前记录返回相关字段值,可以指定C++的各种类型,还可以使用Qt提供的QString和QByteArray类型。其他数据库类型自动映射以适应Qt环境。

使用QSqlQuery类的函数hasFeature()指定Qt支持的数据库特征。通过下列示例代码即可了解数据库支持的结果集大小:

QSqlQuery query;

int numRows;

query.exec(“SELECT * from employee”);

QSqlDatabase defaultDB=QSqlDatabase::database();

if(defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)){

numRows=query.size();

}else{

query.last();

numRows=query.at()+1;

}

插入、修改和删除数据记录

使用QSqlQuery类执行SQL语句。下面是使用INSERT语句插入列表记录的示例代码:

QSqlQuery query;

query.exec(“INSERT INTO employee VALUES (100,’Herry’,21)”);

插入大量记录的方法有两种:通过函数prepare()使用名称绑定,或使用可用位置绑定的占位符:

QSqlQuery query;

query.prepare(“INSERT INTO employee VALUES (:id,:name,:age)”);

query.bindValue(“:id”,100);

query.bindValue(“:name”,’Herry’);

query.bindValue(“:age”,21);

query.exec();

下列示例代码使用位置绑定方法:

QSqlQuery query;

query.prepare(“INSERT INTO employee VALUES (?,?,?)”);

query.addBindValue(100);

query.addBindValue(‘Herry’);

query.addBindValue(21);

query.exec();

只是有函数prepare()即可插入大量记录。使用函数bindValue()和addBIndValue()后,执行函数exec()指定相关记录的字段。在性能方面,占位符的方法可以指定任意的值。下面是修改记录和删除记录的实例:

QSqlQuery query;

query.exec(“UPDATE employee SET name=’Herry’ where id=100”);

query.exec(“DELETE FROM employee where id=100”);

为使用名称绑定处理QMap等绑定属性,Qt使用如下所示的迭代器方法:

QSqlQuery query;

query.exec(“SELECT * from employee”);

QMapIterator<QString,QVariant> i(query.boundValues());

while(i.hasNext()){

i.next();

qDebug()<<i.key().toUtf8().data()<<i.value().toString().toUtf8().data();

}

通过绑定可以使用QList,如下所示:

QSqlQuery query;

query.exec(“SELECT * from employee”);

QList<QVariant> list=query.boundValues().values();

for(int i=0;i<list.size();i++){

qDebug()<<list.at(i).toString().toUtf8().data();

}

事务管理

如果数据库引擎支持事务处理,则可以使用Qt提供的QSqlDriver类的成员函数hasFeature(QSqlDriver::Transactions)指定事务处理。可以使用QSqlDatabase类的成员函数transaction()初始化事务,使用函数commit()提交事务,使用QSqlDatabase类的成员函数rollback()回滚特定事务。

当然,查询事务之前必须启动事务。下面是事务处理示例:

QSqlDatabase::database().transaction();

QSqlQuery query;

query.exec(“SELECT * FROM employee”);

while(query.next()){

int id=query.value(0).toInt();

QString name=query.value(1).toString();

qDebug()<<id<<name;

}

QSqlDatabase::database().commit();

Model类

为了读写QSqlQuery类和数据库的数据,Qt提供了如下模型方式的类:

读写QSqlQuery类和数据库数据的类

类 说明

QSqlQueryModel 读取任意SQL查询的模型方式

QSqlTableModel 单一列表中读写数据的模型方式

QSqlRelationalTableModel 支持外键的QSqlTableModel的子类

这些类均继承自QAbstractTableModel类。为了读写数据库的数据,可以关联QListView类和QTableView类等项目视图类控件的项目数据。

这些类将从数据库读取的数据存储为XML文件,能够轻松转换为文件格式,并且容易实现访问数据库读写数据的方式。

QSqlQueryModel类提供的数据库模型方式

QSqlQueryModel类可以很轻易地将访问数据库读取的数据实现为模型方式。下面是在SQL查询上使用模型方式实例:

QSqlQueryModel model;

model.setQuery(“SELECT * FROM employee”);

for(int i=0;i<model.rowCount();i++){

int id=model.record(i).value(“id”).toInt();

QString name=model.record(i).value(“name”).toString();

qDebug<<id<<name;

}

通过QSqlQueryModel类提供的成员函数setQuery()设置SQL查询。调用成员函数record(int)可以读取保存到数据库列表的记录。

QSqlTableModel类的模型方式

QSqlTableModel类可以读写数据库上的单一列表记录:

QSqlTableModel model;

model.setTable(“employee”);

model.setFilter(“id>10”);

model.setSort(2,Qt::DescendingOrder);

model.select();

for(int i=0;i<model.rowCount();i++){

int id=model.record(i).value(“id”).toInt();

QString name=model.record(i).value(“name”).toString();

qDebug<<id<<name;

}

QSqlTableModel类可以分别搜索、修改每个SQL列表。即使没有SQL语法也可以读取列表数据。通过函数record(int)读取保存到列表的记录数据,使用函数setRecord()修改各行记录。下列实例中,employee表的id字段每次增加10%:

for(int i=0;i<model.rowCount();i++){

QSqlRecord record=model.record(i);

double id=record.value(“id”).toDouble();

id*=id;

record.setValue(“id”,id); //设置record

model.setRecord(i,record); //设置model

}

使用继承自QAbstractItemModel类的成员函数data()和setData()。下面是使用setData()函数更新记录的示例:

model.setData(model.index(row,column),100);

model.submitAll();

下面是插入插入记录的示例:

model.insertRows(row,1); //添加1行

model.setData(model.index(row,0),10);

model.setData(model.index(row,1),”zhangsan”);

model.submitAll();

使用如下方法删除数据:

model.removeRows(row,5); //删除5行

model.submitAll();

QSqlRelationalTableModel类的模型方式

QSqlRelationalTableModel类是支持主键的QSqlTableModel类的扩展类。讲一个列表的字段和其他列表主键指定的字段进行1:1映射,支持外键。

下面是使用QSqlRelationalTableModel类设置外键的代码示例:

QSqlRelationalTableModel model;

model.setTable(“employee”);

model.setRelation(2,QSqlRelation(“city”,”id”,”name”));

model.setRelation(3,QSqlRelation(“country”,”id”,”name”));

函数setRelation()用于设置列表之间的关系,指定employee表和city的第2个字段。

如果使用具有读写功能的QSqlRelationalTableModel类,则可以在GUI的视图上使用QSqlRelationDelegate类。使用该类后,视图将提供组合框控件。

QTableView* view=new QTableView();

view->setModel(model);

view->setItemDelegate(new QSqlRelationalDelgate(view));

列表视图应用

QSqlQueryModel类、QSqlTableModel类和QSqlRelationalTableModel类提供在Qt的QListView、QTableView和QTreeView等视图窗口显示数据的方法。

如下所示,使用QTableView类控件,生成基于SQL数据模型方式的视图:

QTableView* view=new QTableView();

view->setModel(model);

view->show();

在支持读写的模式方式下,可以使用函数setEditTriggers()修改字段:

view->setEditTriggers(QAbstractItemView::NoEditTriggers);

在多个视图下使用同一方式修改数据。使用函数setHeaderData()可以设置模型的头标题:

model->setHeaderData(0,Qt::Horizontal,QObject::tr(“ID”));

model->setHeaderData(1,Qt::Horizontal,QObject::tr(“NAME”));

Qt的数据库(Driver类、Query类、Model类、View类)

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(1)
上一篇 2023年 1月 28日 下午3:57
下一篇 2023年 1月 28日 下午4:03

相关推荐

  • 我的前半生39集电视剧免费看(我的前半生剧集全集)

    第1集 家庭主妇罗子君陷入婚姻危机 唐晶与同行贺涵十年长跑爱情 金色的阳光透过郁郁葱葱的枝头洒落在马路上,花坛里的各色花朵在微凉的海风中轻轻摇摆,不远处有流浪的青年背着吉他悠悠的弹…

    2022年 12月 24日
  • 天下第一行书《兰亭序》,据传是书圣

    东晋永和九年(353年)农历三月初三,会稽内史王羲之和亲朋好友谢安、孙绰等人在兰亭聚会,进行修禊活动。兰亭在今浙江省绍兴市西南13公里处的兰渚山麓,这里绿水青山、风景优美。 修禊是…

    综合百科 2023年 7月 11日
  • rmvb视频怎么转换成mp4格式啊

    rmvb是real公司推出的视频格式,曾经也是网上最为常用的视频文件格式之一,通常被用于保存到本地的多媒体文件中,其最大的优点就是可以在低码率下尽可能的获得更好的画质,文件体积小,…

    2022年 11月 11日
  • 37岁的苍井空,为何隐退娱乐圈,做贤妻良母还遭诽谤

    1983年出生的苍井空,家里孩子挺多的,兄弟姐妹一共7个人,父母也是普通的工人,也无力负担这一大家子,2002年,才19岁的苍井空选择下海拍摄性感影片,这样可以为家里减轻负担!由于…

    2022年 12月 23日
  • 「东方国学原创」“桎梏”是什么东西?

    桎梏是古代木制的狱具,包括桎、梏、拲(gǒng),都是束缚囚犯手脚的狱具。桎是木制脚镣,用圆木或方木中间凿洞,让罪囚把双脚伸进去后用绳索捆牢,有的用木楔连锁,视其罪行轻重来决定时间…

    2022年 11月 5日
  • 清明祭祀,清明祭祀的伤感句子

    三月初,母亲在微信群里张罗姑姑姨姨们给爷爷扫墓。距离清明节还有一段时间,姑姑问这是扫的什么时候的墓?母亲回答:“新坟不过春社。”什么是“春社”?又为什么“新坟不过春社”?我也不解,…

    综合百科 2024年 1月 8日
  • 关于money你真的学明白了吗

    这周发工资啦!助理毛毛要把钱存银行做理财,为给女朋友办一场美美的婚礼。外教看他乐呵呵的,就问怎么了,毛毛说 I'm going to save money for the…

    2023年 3月 9日
  • 一年级下册加减笔画变新字

    在一年级的语文测试中,常常有给一道给汉字加一笔、减一笔或换一笔变一个新字的题目。 今天,媛媛妈就给同学们总结一些考试中最常出现的题目,把这些字记熟,这种题型一定不会丢分! 1. 加…

    2023年 3月 16日
  • “时代的狂,音乐的王”,移动视频彩铃“响我所爱”

    最近几天,周杰伦的粉丝们都在集体“过年”中。继先行曲《最伟大的作品》发布引来微博热搜超7亿次的阅读数后,15日零点,时隔6年,“那个男人”终于带着他的第15张专辑回来了! 全新的数…

    2022年 11月 5日
  • 平面设计比例构成图片

    平面设计图片的比例应该如何把握?图形在广告版面中占主要地位,能够更直观、准确地进行信息传达,表现设计主题。图形在版面中的分布,使画面富有强烈的视觉起伏与极强的视觉冲击力,吸引受众的…

    2022年 11月 5日