QSqlDatabase类提供了通过连接访问数据库的接口。QSqlDatabase的一个实例表示一个数据库连接对象。该连接是通过Qt支持的数据库驱动程序来对数据库的访问,这种数据库驱动程序派生自QSqlDriver。
我们也可以从QSqlDriver继承自己的数据库驱动程序。但这个我还没用过,但是我见过已经有人用过的,当然有官方的源码就可以看看是咋实现的就好啦。
QSqlDatabase 我看官方推荐的就是用静态函数的方式来进行生成对象的。通过调用一个静态 addDatabase() 函数创建一个连接(即,QSqlDatabase的一个实例),其中指定要使用的驱动程序或驱动程序类型(取决于数据库类型)和连接名称。看这个函数声明
一个连接可以通过它自己的名称,也就是connectionName而不是它所连接的数据库的名称来知道。 一个数据库可以有多个连接。QSqlDatabase还支持默认连接的概念,即未命名连接。要创建默认连接,在调用addDatabase()时不要传递连接名称参数。随后,如果调用任何静态成员函数而没有指定连接名称,则假定使用默认连接。但是如果我们有多个连接的时候,就需要指定每一个连接的 connectionName,不然可能会出那个错 QSqlQuery::exec: database not open 我之前就是遇到这个错误的。
下面的代码片段展示了如何创建和打开到PostgreSQL数据库的默认连接:
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("acidalia");
db.setDatabaseName("customdb");
db.setUserName("mojito");
db.setPassword("J0a1m8");
bool ok = db.open();
创建QSqlDatabase对象后,使用设置连接参数。
然后调用open()来激活到数据库的物理连接。在您打开连接之前,连接是不可用的。
上面定义的连接将是默认连接,因为我们没有给addDatabase()提供连接名称。随后,你可以调用database(),不带连接名参数,得到默认连接:
QSqlDatabase db = QSqlDatabase::database();
可以看看我之前的连接 SQLsever数据库的一个博客:Qt 连接并使用 SQL Sever数据库
创建一个使用类型引用的驱动程序的QSqlDatabase连接。如果无法识别该类型,则数据库连接将没有任何功能。
目前可用的驱动程序类型有:
Driver Type | Description |
---|---|
QDB2 | IBM DB2 :就是 IBM 公司的 DB2数据库驱动 |
QIBASE | Borland InterBase Driver |
QMYSQL | MySQL 驱动 |
QOCI | Oracle Call Interface Driver:Oracle 驱动 |
QODBC | ODBC Driver (includes Microsoft SQL Server) :ODBC的基本思想是为用户提供简单、标准、透明的数据库连接的公共 编程接口,其他数据库驱动基本上都是可用 |
QPSQL | PostgreSQL 驱动 |
QSQLITE | SQLite version 3 or above |
QSQLITE2 | SQLite version 2 |
QTDS | Sybase Adaptive Server |
如果想使用自己实例化的驱动程序创建数据库连接时,上面的重载非常有用。它可能是我们自己的数据库驱动程序,或者需要自己实例化其中一个Qt驱动程序。如果这样做,建议在应用程序中包含驱动程序代码。例如,你可以用你自己的QPSQL驱动程序创建一个PostgreSQL连接,如下使用的是标准的数据库驱动所示:
#include "qtdir/src/sql/drivers/psql/qsql_psql.cpp" //这个位置在我的Qt 5.14.2 的位置在下图
PGconn *con = PQconnectdb("host=server user=bart password=simpson dbname=springfield");
QPSQLDriver *drv = new QPSQLDriver(con);
QSqlDatabase db = QSqlDatabase::addDatabase(drv); // becomes the new default connection
QSqlQuery query;
query.exec("SELECT NAME, ID FROM STAFF");
...
下面就是源码中Qt官方数据库的驱动源码,也就是上面 include的位置
上面的代码设置了一个PostgreSQL连接并实例化了一个QPSQLDriver对象。接下来,调用addDatabase()将连接添加到已知的连接中,以便Qt SQL类可以使用它。当使用连接句柄(或一组句柄)实例化一个驱动程序时。
请记住,必须将应用程序链接到数据库客户端库。确保数据库驱动库在链接器的搜索路径中,当然这个是使用自定义的库才需要,使用Qt提供的驱动就不用啦,并在你的.pro文件中添加如下行:
unix:LIBS += -lpq
win32:LIBS += libpqdll.lib
所描述的方法适用于所有提供的驱动程序。唯一的区别在于驱动构造函数的参数。下面是Qt中包含的驱动程序及其源代码文件和构造函数参数的表格。
驱动名 | 类名 | 构造参数 | 需要包括的cpp |
---|---|---|---|
QPSQL | QPSQLDriver | PGconn *connection | qsql_psql.cpp |
QMYSQL | QMYSQLDriver | MYSQL *connection | qsql_mysql.cpp |
QOCI | QOCIDriver | OCIEnv *environment, OCISvcCtx *serviceContext | qsql_oci.cpp |
QODBC | QODBCDriver | SQLHANDLE environment, SQLHANDLE connection | qsql_odbc.cpp |
QDB2 | QDB2 | SQLHANDLE environment, SQLHANDLE connection | qsql_db2.cpp |
QTDS | QTDSDriver | LOGINREC *loginRecord, DBPROCESS *dbProcess, const QString &hostName | qsql_tds.cpp |
QSQLITE | QSQLiteDriver | sqlite *connection | qsql_sqlite.cpp |
QIBASE | QIBaseDriver | isc_db_handle connection | qsql_ibase.cpp |
QSqlDatabase是一个值类。通过QSqlDatabase的一个实例对数据库连接所做的更改将影响表示相同连接的其他QSqlDatabase实例。使用cloneDatabase()在现有数据库的基础上创建一个独立的数据库连接。
最好将QSqlDatabase的副本作为类的成员保存,因为这将防止在关闭时正确清除实例。如果需要访问已存在的QSqlDatabase,应该使用database()来访问。 如果选择使用QSqlDatabase成员变量,则需要在删除QCoreApplication实例之前删除该成员变量,否则可能导致未定义的行为。
如果创建多个数据库连接,请在调用addDatabase()时为每个连接指定唯一的连接名。使用database()和连接名来获取该连接。使用removeDatabase()和连接名来删除连接。如果您试图删除由其他QSqlDatabase对象引用的连接,QSqlDatabase将输出警告。使用contains()检查指定的连接名是否在连接列表中。
函数名 | 含义 |
---|---|
tables() | 返回数据库的所有表 |
primaryIndex() | 返回一个表的主键 |
record() | 返回表字段的元信息 |
transaction() | 启动事务 |
commit() | 保存并完成所有操作 |
rollback() | 回滚取消操作 |
lastError() | 返回关于上次错误的信息 |
drivers() | 返回可用SQL驱动程序的名称 |
isDriverAvailable() | 检查是否有特定的驱动程序可用 |
registerSqlDriver() | 注册一个定制的驱动程序 |
注意:QSqlDatabase::exec()已弃用。请改用QSqlQuery::exec()。
注意:当使用事务时,必须在创建查询之前开始事务。