先来看下这段代码
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "MyConnection1");
QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "MyConnection2");
qDebug() << QSqlDatabase::connectionNames();
qDebug() << db1.isValid();
QSqlDatabase::removeDatabase("MyConnection1");
qDebug() << QSqlDatabase::connectionNames();
qDebug()<<db1.isValid();
这段代码首先创建了两个数据库的连接,然后移除掉了其中一个
这段代码的输出如下:
(“MyConnection1”, “MyConnection2”)
true
QSqlDatabasePrivate::removeDatabase: connection ‘MyConnection1’ is still in use, all queries will cease to work.
(“MyConnection2”)
false
可以发现,在移除MyConnnection1时,Qt弹出了警告,这是因为在删除MyConnection1时,当前作用域内,还存在一个使用MyConnection1的对象db1, 这个时候,db1变成了无效的,如果我们还继续对db1进行操作,是不安全的。所以Qt会非常人性化的给出了警告。
正确的删除方法应该是这样:
{
QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "MyConnection1");
}
QSqlDatabase::removeDatabase("MyConnection1");
用括号限定了db1的作用域,当删除的时候,就已经没有使用MyConnection1的对象了,这时候删除,Qt就不会弹出警告了。
不过这种写法在实际应用中,没有什么可用之处,下面介绍一个十分好用的写法:
QSqlDatabase GetDataBase(QString connectionName)
{
if (QSqlDatabase::connectionNames().contains(connectionName))
return QSqlDatabase::database(connectionName);
return QSqlDatabase::addDatabase("QSQLITE", connectionName);
}
将获取QSqlDataBase的对象封装成函数,指定连接名称,返回QSqlDataBase对象,如果已经存在了相应的连接,则直接返回存在的QSqlDataBase对象。在程序中,可以直接使用GetDataBase().open() 这种方式来操作数据库,由于GetDataBase()返回的是一个临时对象的拷贝,脱离它的作用域后,用完就会自动释放。
这样写有两点好处:
1、可以在程序的任意地方使用QSqlDataBase::removeDatabase()来删除一个连接,而不会弹出警告
2、从某种程度上,这种方法实现了数据库的单例模式,无论何时,都只会有一个名称为connectionName的连接