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

相关推荐

  • 盘点那些年范冰冰带给我们的那些经典作品

    范冰冰!1981年9月16日出生于山东青岛,演员,歌手。毕业于上海师范大学谢晋影视艺术学院。1996年参演电视剧《女强人》,这是范冰冰生平演的第一部戏,剧中角色是一个小媳妇! 19…

    2022年 12月 28日
  • 如何家庭自制凉皮,在家自制凉皮全过程

    最近凉皮火了,教你最详细凉皮配方,爽滑劲道还不硬,吃了还想吃。大家好,我是傻姐美食,生活中唯有美食和美景不可辜负。最近凉皮这种美食突然在正月里火了起来,夏日小吃火在了冬天,因为不能…

    2024年 1月 5日
  • 成语兵不厌诈是什么意思

    东汉安帝在位时(公元107~125年),西南部的几个羌族部落经常骚扰边境。有一次竟把汉朝的武都郡层层包围。 当时情势危急,安帝连忙命虞诩为武都郡太守,率命抵抗羌军。当部队到达陈仓一…

    2022年 12月 7日
  • 型男范 | 照镜子别只看正面,背影如果这样就太减分了

    男装定制圣地——英国萨维尔街——流传着一个关于裁缝的业内笑话: 做西装裤的裁缝比不上做西装外套的裁缝。 作为整个造型的核心,制作西装外套是一个相当复杂的过程。它需要使用各种材料,经…

    2023年 10月 15日
  • 美国国防部最近确定的ufo影像

    4月21日消息,据以色列《耶路撒冷邮报》网站报道,美国一架无人机在中东发现不明飞行物,而且相关的飞行画面也遭到曝光。从画面来看,这是一个半透明状银色球体。负责此事的美国防务官员肖恩…

    2023年 6月 4日
  • 我的朋友,我心中的天使:折翼的天使是什么歌

    我有一个在网上认识的朋友,网名:折翼的天使,女性。 和她相识,也许是天意,也许是一种机缘巧合,我们同在某个班群里学习,因为人太多,吵吵嚷嚷,很是烦心,有人建议另建小群以便相互交流,…

    综合百科 2023年 2月 25日
  • 反物质世界

    编者按:关于反物质,我刊从1997年第11期《反地球在哪里?》到2017年第8期《反物质之谜》,二十年来多次从各个方面介绍了反物质,下面这一篇文章对反物质的去向做了与众不同的解释。…

    2022年 12月 12日
  • 核显花屏是主板问题吗

    显卡花屏,在电脑使用中还是很常见的,这个故障在使用独显的电脑中很常见,在使用CPU核显的电脑中还是比较罕见的! 老规矩,直接上维修实例,不墨迹! 一顾客,电脑在使用过程中,时不时的…

    2023年 10月 9日
  • 为什么有些i7处理器的电脑那么便宜

    英特尔的酷睿I7处理器是消费级市场的高端产品,也是很多电脑用户的追求。对于台式机用户来讲,不买i7处理器,我们往往会说因为价格高,比如拿最新的8代酷睿来说,I7 8700/K拥有六…

    2022年 11月 5日
  • dnf百分比吃独立攻击吗

    在众多职业中分为百分比和独立攻击力职业,很多人是否会有疑问,这两者到底有何区别?难道不是都一样吗?如果你这样想就大错特错。 百分比职业需要物攻和力量的加持,这样才能增加最大输出伤害…

    2022年 12月 5日