问题:
很多QT新手多线程使用数据库时,经常遇到警告:
QSqlDatabasePrivate::database: requested database does not belong to the calling thread.
究其原因,帮助助手明确说明
Threads and the SQL ModuleA connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported.
也就是在QT里,数据库的连接对象,只能在本线程中使用,不能跨线程使用。
在多线程中便利使用数据库:
1)实现连接函数,使用线程ID作为连接名
bool MySQL::connectDb(QString& errorMsg)
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", QString::number((quint64)QThread::currentThreadId())); //连接的MYSQL的数据库驱动
db.setHostName("127.0.0.1"); //主机名
db.setPort(3306); //端口
db.setDatabaseName("Test"); //数据库名
db.setUserName("root"); //用户名
db.setPassword("test123456"); //密码
if (!db.open())
{
errorMsg = db.lastError().text();
qDebug() << "open database failed:" << errorMsg;
return false;
}
return true;
}
2)实现断连函数
void MySQL::disconnectDb()
{
QString dbName = QString::number((quint64)QThread::currentThreadId());
{
QSqlDatabase dbConnected = QSqlDatabase::database(dbName);
if (dbConnected.isValid())
{
dbConnected.close();
}
}
QSqlDatabase::removeDatabase(dbName);
}
注意QSqlDatabase::database(dbName);这句要写在大括号里,否则QSqlDatabase::removeDatabase时会报警告:
QSqlDatabasePrivate::removeDatabase: connection '191340' is still in use, all queries will cease to work.
因为调用QSqlDatabase::database(dbName)会使连接的引用计数+1,调用QSqlDatabase::removeDatabase时,连接的引用计数不为1就会报如上警告。
使用示例:
//伪代码
std::thread([](){
MySql db;
//在线程里连接数据库
QString errText;
db.connectDb(errText);
//读写数据库
db.select...
db.insert...
...
//断开数据库
db.disconnectDb();
)



