0、说明

QSqlDatabase类处理与数据库连接相关的操作。一个QSqlDatabase实例就代表了一个连接,连接时要提供访问数据库的driver,driver继承自QSqlDriver。

通过静态方法addDatabase()构造一个QSqlDatabase来构造一个连接,调用这个方法时可以指定driver或driver type和连接名。

不同连接通过连接的name进行区分,而不是它要连接的数据库的name。我们可以通过多种连接连接到一个数据库。QSqlDatabase也支持默认连接——无名连接。为了构造这个默认连接,当我们调用addDatabase()时,不传入连接name。之后,当我们调用任何static成员函数时,如果不指定连接名,都会采用该默认连接。

下面的代码段展示了如何构造一个默认连接来连接一个PostgreSQL database:

    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("Administrator");
db.setDatabaseName("Mydb");
db.setUserName("User");
db.setPassword("123456");
bool ok = db.open();

构造完成QSqlDatabase对象之后,要分别调用setHostName()、setDatabaseName()、setUserName()、setPassword()、setPort()、setConnectOptions()来设置连接配置项。之后,调用open()方法激活和数据库的连接。在open()之前,连接是不可用的。

上文我们构造了一个默认连接,因为我们在调用addDatabase()时并没有给这个连接命名。接下来,我们可以通过调用database()来得到这个默认连接对应的QSqlDatabase对象:

QSqlDatabase db = QSqlDatabase::database();

QSqlDatabase是一个值相关类,也就是说,在这个连接上进行的操作会影响到其它代表同一个连接的QSqlDatabase对象的内容。调用cloneDatabase()可以用已存在的连接构造一个独立的数据库连接。

注意

强烈推荐不要为QSqlDatabase构造副本,不然可能会在关闭时导致清理异常。如果我们需要访问一个存在的QSqlDatabase,应该通过database()来进行。如果我们获取并记录了一个QSqlDatabase类型的成员字段,那么它在QCoreApplication实例关闭前需要将其delete。

如果我们构造了多个连接,那么需要在调用addDatabase()时为每个连接指定一个独特的名字。通过调用database()时传入连接名来获取对应的连接。

调用removeDatabase()并传入相应的连接名来实现取消连接。如果我们想关闭一个正在被其他QSqlDatabase使用的连接,那么会输出一个警告信息。可以调用contains()可以检查某个连接名是否包含在连接List中。

QSqlDatabase::exec()已经过时了,现在应该用QSqlQuery::exec()。

使用事务时,必须在创建查询前启动事务。

1、模块和加载项

Header: #include <QSqlDatabase>
qmake: QT += sql

2、构造

QSqlDatabase(QSqlDatabase other) 复制一个QSqlDatabase
QSqlDatabase()

构造一个空的、非法的QSqlDatabase。

需要使用addDatabase()、removeDatabase()、database()来获取合法的QSqlDatabase

通常不用构造方法构造一个QSqlDatabase,而用静态方法addDatabase()。

5、静态方法

返回值类型

方法

说明

QSqlDatabase

addDatabase(QString type, QString connectionName = QLatin1String(defaultConnection))

addDatabase(QSqlDriver *driver, QString connectionName = QLatin1String(defaultConnection))

用driver type和连接名构造一个连接,如果和之前的连接重名,那么会删除之前的连接,而返回新构造的连接。

如果type不可用,isValid()会返回false。

如果连接名未指定,那么新构建的连接将成为默认连接,可以通过调用无参database()来访问这个默认连接。如果提连接名,将会返回连接名对应的连接。

如果多次调用该方法且不指定连接名,那么后建立的默认连接会覆盖之前的默认连接。

在使用连接前,需要先初始化,也就是调用 setDatabaseName(), setUserName(), setPassword(), setHostName(), setPort(), and setConnectOptions()这些方法或其中的一些方法。最后,open()

该方法用一个driver来实例化数据库连接,这个driver可以是我们自写的。

这个方法我们用到的比较少,有需要的可以去官网查看addDatabase

QSqlDatabase

cloneDatabase(QSqlDatabase other, QString connectionName)

cloneDatabase(QString other, QString connectionName)

复制一个连接,返回它的副本,并为该副本命名。

所有原连接的内容如databaseName()、hostName()都会原封不动的保存下来。

这个新的连接并不是open的,在使用它之前,要先用open()打开。

QStringList connectionNames() 返回包含所有连接名的QStringList
bool contains(QString connectionName = QLatin1String(defaultConnection)) 如果连接名List中包含指定连接名,返回true
QSqlDatabase database(QString connectionName = QLatin1String(defaultConnection), bool open = true)

返回指定连接名的连接。

如果参数open = true(默认),那么如果返回的连接原本没有open,那么现在它会open。

如果不指定连接名,会返回默认连接;如果连接名不存在,会返回一个非法连接。

该方法是线程安全的。

QStringList drivers() 返回所有可用的drivers组成的QStringList
bool isDriverAvailable(QString name) 如果名字为name的driver可用,就返回true
void registerSqlDriver(QString name, QSqlDriverCreatorBase *creator)

注册一个新的名为name的driver。

如果我们有一个定制SQL driver并且并不想将它编译成一个接口时,可以调用该方法。

void removeDatabase(QString connectionName)

在连接List中删除某个连接。

需要注意的是,在该连接上不能有某个启动的Query,否则可能导致资源泄漏。

也就是说,Query语句必须与removeDatabase不在一个代码块中

错误示范:

// WRONG
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
QSqlDatabase::removeDatabase("sales"); // will output a warning
// "db" is now a dangling invalid database connection,
// "query" contains an invalid result set

正确示范:

{
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// 当db和query离开代码块之后,它们就会被销毁,此时再销毁是安全的
QSqlDatabase::removeDatabase("sales"); // correct

为了移除默认连接,可以通过database().connectionName()来获取默认连接name。

该方法是线程安全的。

QString的Drive type

Driver Type Description
QDB2 IBM DB2
QIBASE Borland InterBase Driver
QMYSQL MySQL Driver
QOCI Oracle Call Interface Driver
QODBC ODBC Driver (includes Microsoft SQL Server)
QPSQL PostgreSQL Driver
QSQLITE SQLite version 3 or above
QSQLITE2 SQLite version 2
QTDS Sybase Adaptive Server

6、实例方法

返回值类型

方法

说明

QSqlDatabase & operator=(QSqlDatabase other) 赋值
void close() 关闭连接,释放所有资源,取消建立在该连接上的所有查询相关的QSqlQuery对象
bool commit()

如果driver支持事务,那么就向数据库提交事务,此时transaction()会启动。如果操作成功,返回true。

对于某些数据库,当在数据库上有活动查询正在执行,那么事务提交会失败并返回false。在事务提交之前应使查询失效。

调用lastError()可以得知错误信息。

QString connectOptions() 返回该连接所用到的一些连接配置
QString connectionName() 返回连接名
QString databaseName() 返回数据库名
QSqlDriver * driver() 返回该连接用的QSqlDriver
QString driverName() 返回driver名
QSqlQuery exec(QString query = QString()) 执行一段SQL语句,返回QSqlQuery对象。
QString hostName() 返回连接的Host名
bool isOpen() 连接是否open
isOpenError()

是否存在打开错误。

错误信息通过lastError()查询

isValid()

如果该QSqlDatabase有一个合法driver返回true。

QSqlDatabase db;
qDebug() << db.isValid(); // Returns false db = QSqlDatabase::database("sales");
qDebug() << db.isValid(); // 如果连接"sales"存在,返回true QSqlDatabase::removeDatabase("sales");
qDebug() << db.isValid(); // Returns false
QSqlError lastError()

返回最近的错误信息。

查询相关的错误会被QSqlQuery::lastError()抛出

QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() 返回当前数据库连接的默认精度策略。
bool

open()

open(QString user, QString password)

启动一个数据库连接
QString password() 返回连接密码
int port() 返回连接端口
QSqlIndex primaryIndex(QString tablename 返回表tablename上的索引。
QSqlRecord record(QString tablename) 返回表tablename(或视图)上所有字段组成的QSqlRecord
bool rollback() 如果事务transaction()已经启动,回滚数据库上的事务。

void

这些方法必须在连接open()前调用,否则是无效的。

不然就只能先close(),再调用该方法,再open()。

setConnectOptions(QString options = QString())

设置连接配置项。

参数options字符串是以分号';'分隔的option=value对。不同的数据库的配置是不同的,具体可查看官方文档setConnectOptions

setDatabaseName(QString name)

设置数据库名。

如果数据库服务器上有多个数据库,就要用该项指明用哪个数据库。

setHostName(QString host) 设置Host名(服务器IP/域名)。
setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy) 设置数字精度策略。
setPassword(QString password) 设置密码。
setPort(int port) 设置端口。
setUserName(QString name) 设置用户名。
QStringList tables(QSql::TableType type = QSql::Tables) 返回数据库中所有的table、system table、view构成的QStringList,具体返回哪种,由参数type指定。
bool transaction() 启动一项事务,成功则返回true
QString userName() 返回用户名

事务

在以上方法中,我们提到了事务(transaction)一词,它的意思是我们对数据库进行的各项操作,需要注意的是,对数据库修改的事务,必须commit()提交事务,才能真正实现对数据库修改,否则只是对它的映像进行修改。

7、用法

1)构造数据库连接

int main(int argc, char *argv[])
{
QSqlDatabase db =QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("Mysql");
db.setPort(1234);
db.setUserName("User");
db.setPassword("pwd1");
db.setDatabaseName("Table1");
if( !db.open() ){ //数据库打开失败
qDebug()<<db.lastError().text();
}
}

Qt:QSqlDatabase的更多相关文章

  1. Qt:禁止qDebug的输出

    Qt:禁止qDebug的输出 在工程的.pro文件里加上以下编译批令即可: DEFINES += QT_NO_DEBUG_OUTPUT

  2. Qt:使用自定义的字体

    Qt:使用自定义的字体 1. 下载字体文件 2. 加载字体文件 3. 使用字体   QFontDatabase::addApplicationFont("XENOTRON.TTF" ...

  3. Qt:QJsonObject

    0.说明 QJsonObject在逻辑上就是一个Map或Dict!记住这一点对理解它的方法.说明很有帮助. QJsonObject类封装了JSON Object. JSON Object是一个Key- ...

  4. Qt:QJsonValue

    0.说明 QJsonValue类用于操作JSON中的各种数据. JSON是用于存储结构化数据的格式,JSON中的数据可以是六种类型: 基本类型 存储类型 bool QJsonValue::Bool d ...

  5. Qt:QJsonArray

    0.说明 QJsonArray中存储了一系列的QJsonValue.可以向其中插入.删除QJsonValue. 一个QJsonArray可以与QVariantList互相转换.可以通过size()访问 ...

  6. Qt:QUrl构造时的qrc前缀

    参考(按对我帮助从大到小排列): Qt内的各种路径(让人迷惑) - 鬼谷子com - 博客园 qt webengineview 加载本地资源方式 - beautifulday - 博客园 (17条消息 ...

  7. 解决方式:QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins

    在用QSqlDatabase时遇到报错QSqlDatabase: an instance of QCoreApplication is required for loading driver plug ...

  8. Qt:QSqlQuery

    0.说明 QSqlQuery提供了执行SQL代码的方法. QSqlQuery封装了在QSqlDatabase中查询.检索数据的相关函数.它可以用来执行如SELECT.INSERT.UPDATE.DEL ...

  9. Qt:正则表达式语法:

         正则表达式是验证输入.从输入中提取数据以及对输入进行搜索和替换的强大工具,所谓正则表达式,regexp是一种利用模式匹配语言来描述字符串组成限制条件的方式;        Qt 提供了一个Q ...

随机推荐

  1. 总是记不住但又总是要用的css

    有没有经常遇到一些样式每次写都要用百度呢?我收集了一些我平时经常要用到的但又总是记不住的样式.有错误的地方欢迎指正.转载请注明出处. 一.设置input 的placeholder的字体样式 input ...

  2. kubernetes之Pod水平自动伸缩(HPA)

    https://k8smeetup.github.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ Horizon ...

  3. python 小兵(8)闭包和装饰器

    闭包"是什么,以及,更重要的是,写"闭包"有什么用处. (个人理解) 1."闭包"是什么 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 ...

  4. 推荐一个基于Dapr的 Red Dog 的完整微服务应用程序

    微服务尽管构建起来非常困难,但它们已成为一种越来越流行的架构模式.随着开发人员开始将他们现有的单体代码库迁移到微服务系统,他们花费大量时间来处理分布式应用程序带来的固有挑战,例如状态管理和服务调用.通 ...

  5. 初步认识微前端(single-spa 和 qiankun)

    初步认识微前端 微前端是什么 现在的前端应用,功能.交互日益复杂,若只由一个团队负责,随着时间的推进,会越来越庞大,愈发难以维护. 微前端这个名词,第一次提出是在2016年底.它将微服务(将单一应用程 ...

  6. Java-方法的递归调用

    方法的递归是指在一个方法的内部调用自身的过程.递归必须要有结束条件,否则将陷入无限递归的状态,永远无法结束调用. 代码 public class Example24{ public static vo ...

  7. AESUtil_1

    package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher; ...

  8. smartimageview 的原理

    自定义的控件在布局文件中的引用都需要指定类的完整路径 1.自定义了一个MyImageview类继承了Imageview,添加三个构造方法     2.添加一个setImageUrl方法接受一个图片ur ...

  9. Sping高质量博文链接集合

    1. Spring事务传播行为详解 https://segmentfault.com/a/1190000013341344

  10. 今天带大家了解一下ICMP协议及基本使用

    ICMP协议的介绍及基本使用 1.IP数据包头的格式 2.ICMP协议的功能介绍 3.ICMP的基本使用方法 1.在讲解ICMP协议之前,我们先来简单了解一下IP数据包格式如图所示: 2.好现在切入正 ...