Qt addDatabase 引发的connection ‘qt_sql_default_connection‘ is still in use

项目场景:

Qt 使用 代码进行数据库数据的拷贝,将一个数据库中的数据导入另一个数据库。


问题描述:

这时是需要同时连接两个数据库的,但是在连接第二个数据前addDatabase时引发了Qt的警告

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all

queries will cease to work.

意思是说已经有数据库引用了默认的数据库连接名。
而且:如果忽略该警告,Qt官方文档里也写了,可能会出现内存泄漏:

Warning: There should be no open queries on the database connection when this function is called,

otherwise a resource leak will occur.

不管是不是有其他问题,警告都是不应该存在的,那么该如何分析这个问题呢?


原因分析:

既然已经确定是这条语句引起的警告,那么我们就要分析这个语句了。
首先我们来看这个函数说明

[static] QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection))
Adds a database to the list of database connections using the driver type and the connection name connectionName. If there already exists a database connection called connectionName, that connection is removed.
The database connection is referred to by connectionName. The newly added database connection is returned.
If type is not available or could not be loaded, isValid() returns false.
If connectionName is not specified, the new connection becomes the default connection for the application, and subsequent calls to database() without the connection name argument will return the default connection. If a connectionName is provided here, use database(connectionName) to retrieve the connection.
Warning: If you add a connection with the same name as an existing connection, the new connection replaces the old one. If you call this function more than once without specifying connectionName, the default connection will be the one replaced.
Before using the connection, it must be initialized. e.g., call some or all of setDatabaseName(), setUserName(), setPassword(), setHostName(), setPort(), and setConnectOptions(), and, finally, open().

这里其实已经说明了,每一个连接都要有连接名,如果没有指定连接名,或者连接名重复—>那么将会删除旧的连接,并且Qt官方文档已经明确给了警告。但是为什么我们还是出错了呢?
好,我们看一下我们是如何调用的

...
m_db = QSqlDatabase::addDatabase(driver);
...

看到了吧,这里我们忽略了第二个参数,而Qt这里会默认参数为默认值,所以第二次调用时会返回默认连接已经被使用。


解决方案:

既然已经清楚问题原因了,那么我们只需要针对性的修改即可,将第二个参数写进去。

...
m_db = QSqlDatabase::addDatabase(driver, connectionName);
...

但是,你有没有思考过为什么会出现这个问题:
习惯性的依赖记忆去写代码,并没有阅读函数说明,所以我们在调用某些系统库函数要同调用他人的接口时一样,仔细阅读相关说明和参数解释,以免出现意外,这是代码较少的情况下可以去分析那条代码出现的问题,如果代码量很大时就很难去分析了。

最后,提出一个问题:Qt的connect函数连接信号与槽,你知道有几个参数吗?connect也有参数坑

你可能感兴趣的:(Qt)