QSqlQuery 类为执行SQL语句和浏览查询结果上提供了交互接口。
QSqlQueryModel类和QSqlTableModel在访问数据库上提供了更高水平的接口,这两个类将在下一部分进行说明。如果你不熟悉SQL,那么你可以直接查看下一部分(Using the SQL Model Class)。
执行一条语句
要执行一条SQL语句,你可以创建一个QSqlQuery 对象,然后调用QSqlQuery:exec()函数,如下:
QSqlQuery 的构造函数接受一个可选的QSqlDatabase对象作为参数,用来指定要使用的数据库。在上述例子中,QSqlQuery 对象在构造时没有传参来指定数据库,所以会使用默认的数据库连接。如果发生了错误,exec()函数会返回false。之后可以使用QSqlQuery:lastError()函数来查看错误。
浏览查询结果
QSqlQuery 类可以逐一访问结果集的每一条记录。在调用exec()函数后,QSqlQuery 的内部指针会指向第一条记录之前的位置。我们必须调用QSqlQuery:next()函数将指针指向第一条记录,之后通过反复调用next()函数来获取其他记录,直到next()函数返回false。以下是一个典型的循环来遍历所有记录:
QSqlQuery:value()函数返回当前记录的指定字段的值。字段从0开始进行索引。QSqlQuery::value()函数返回一个QVariant类对象,它支持各种C++和Qt的核心数据类型,例如int,QString,QByteArray。数据库中不同的类型会自动映射到Qt中最接近等效的类型。在代码中,通过调用QVariant:toString() 和QVariant:toInt()函数将变体类型分别转换为QString类型和int类型。对Qt所支持的数据库类型的推荐概述,请参见此表。你可以使用QSqlQuery::next(), QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last(), 和QSqlQuery::seek()函数对结果集进行反复查询。可以使用QSqlQuery:at()函数来获取当前行的索引,在数据库支持的情况下,可以使用QSqlQuery:size()函数来获取结果集的总行数。使用QSQLDriver:hasFeature()函数可以确定一个数据库是否支持给定的特性。在下面的例子中,如果数据库支持size特性,通过调用QSqlQuery:size()函数来获取结果集的记录数,不然,通过访问最后一条记录,利用记录的位置来总的记录数。
如果你在遍历结果时只通过传递正整数值来调用函数next() seek(),那么,你可以在调用exec()函数前,调用QSqlQuery::setForwardOnly(true)。在针对大数据结果集进行操作时,这个简单的做法会显著的加快查询的速度。
插入,更新,删除记录
QSqlQuery 类可以执行任意的SQL语句,不单单是select。下面的例子说明了如何使用insert 将一条记录插入数据表中:
如果你想要同时插入多条记录,那么将真实的数据和SQL语句分开是一种比较有效的做法。这就要用到占位符。Qt支持两种占位符语法:命名绑定和位置绑定。下面是命名绑定的例子:
位置绑定示例:
以上两种语法在Qt支持的数据库中都是有效的。如果数据库本就支持上述语法,那么Qt就会简单的将语句转发给数据库系统进行执行;否则,Qt会通过预处理查询来模拟占位符语法。最后,数据库执行的真正语句可以通过QSqlQuery:executedQuery()函数获得。需要插入多条记录时,只需要提前调用一次QSqlQuery:prepare()函数。之后你可以在调用exec()函数之前,根据需要调用bindValue()或者 addBindValue()函数。除了性能,使用占位符的另外一个优点在于,你可以指定任意值而不用担心转义字符的问题。
更新一条记录和插入记录类似:
你同样可以使用命名绑定或者位置绑定将参数值和真值关联起来。
最后,这是删除语句的例子:
事务处理
如果基础数据库引擎支持事务处理,那么 QSqlDriver::hasFeature(QSqlDriver::Transactions) 函数的返回值为true。首先使用 QSqlDatabase::transaction()来启动事务,其次为要执行的SQL命令,最后调用 QSqlDatabase::commit() 或者 QSqlDatabase::rollback()函数。当使用事务创建查询之前,首先要启动事务。
例子:
事务机制的使用是用来保证一个复杂操作的原子性(举个例子,查询一个外键和增加一条记录),或是提供一种消除中间复杂性变化的手段。