这里写自定义目录标题
主要目的是为了记录自己踩过的坑。
在子线程中读取数库内容时,按照在子线程中的run函数中创造数据的链接并查询,在第一次使用子线程的时候,可以正常运行,在重复使用的时候,则可能会报错:
下面为子线程的run函数:
```cpp
void run(){
QSqlDatabase *db=new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"));
QStringList list = QSqlDatabase::drivers();
qDebug()<<list;
db->setDatabaseName("BugRecord.db");//数据库的名字
//打开数据库
bool ok = db->open();//如果不存在就创建,存在就打开
if(ok)
{
qDebug()<<"数据库创建(打开)成功了";
}
else
{
qDebug()<<db->lastError();//调用上一次出错的原因
exit(-1);
}
QSqlQuery query(QString("select * from test"),*db);
//查询后,读取数据
while (query.next()) {
QString name = query.value(1).toString();
int salary = query.value(0).toInt();
qDebug() << name << salary;
}
}
``
如果第二次调用子线程读取数据的时候,就会出现:
QSqlDatabasePrivate::removeDatabase: connection ‘qt_sql_default_connection’ is still in use, all queries will cease to work.
QSqlDatabasePrivate::addDatabase: duplicate connection name ‘qt_sql_default_connection’, old connection removed.`
主要的原因时重复调用子线程的时候,链接的名称相同,旧的链接没有清除掉,因此会报错
修改为:
void run(){
QSqlDatabase db;
if(QSqlDatabase::contains("qt_sql_default_connection"))
db = QSqlDatabase::database("qt_sql_default_connection");
else
db = QSqlDatabase::addDatabase("QSQLITE");
QString connectionName =db.databaseName();
if(connectionName.isEmpty()){
connectionName = "BugRecord.db";
}
qDebug()<<connectionName;
{
// mutex.lock();
//db.setHostName("127.0.0.1");
db.setDatabaseName(connectionName);
//db.setUserName("root");
// db.setPassword("1234");
if (!db.open())
{
qDebug() << "thread 1 open db failed!";
}
QSqlQuery query(QString("select * from test"),db);
//查询后,读取数据
while (query.next()) {
QString name = query.value(1).toString();
int salary = query.value(0).toInt();
qDebug() << name << salary;
}
query.clear();
// mutex.unlock();
qDebug() << "thread 1: " << QThread::currentThreadId() << connectionName;
}
QSqlDatabase::removeDatabase(connectionName);
}
多次调用后的结果为
“BugRecord.db”
“nihao” 1
“xioaming” 2
thread 1: 0x554 “BugRecord.db”
“BugRecord.db”
“nihao” 1
“xioaming” 2
thread 1: 0xa78 “BugRecord.db”
“BugRecord.db”
“nihao” 1
“xioaming” 2
thread 1: 0x4c1c “BugRecord.db”
表示每次运行的结果都时正常的,由于只有子线程thread1这一个线程访问数据库,因此在代码中是否加所运行的结果都是一样的。这两种方法的主要区别在于:
1,第一种方法没有检查链接的名称是否一致。
2,第一种方法在使用完毕以后没有清理链接。