dai*_*isy 29 database qt qt4 qtsql
我对手册感到困惑,我应该像这样工作:
{
QSqlDatabase db = QSqlDatabase::addDatabase (...);
QSqlQuery query (db);
query.exec (...);
}
QSqlDatabase::removeDatabase (...);
Run Code Online (Sandbox Code Playgroud)
正如文件所指出的,query或db将被自动解构.但这有效吗?
好吧,如果我db在一个类中缓存,如下所示:
class Dummy {
Dummy() {
db = QSqlDatabase::addDatabase (...);
}
~Dummy() {
db.close();
}
bool run() {
QSqlQuery query (db);
bool retval = query.exec (...);
blabla ...
}
private:
QSqlDatabase db;
};
Run Code Online (Sandbox Code Playgroud)
有时我会看到警告:
QSqlDatabasePrivate::removeDatabase: connection 'BLABLA' is still in use, all queries will cease to work.
Run Code Online (Sandbox Code Playgroud)
即使我没有打电话run().
ale*_*sdm 46
QSqlDatabase使用addDatabase或在调用时创建对象时removeDatabase,只是将元组(驱动程序,主机名:端口,数据库名称,用户名/密码)与名称关联或取消关联(如果未指定,则为默认连接名称)连接名称).
SQL驱动程序已实例化,但只有在调用时才会打开数据库QSqlDatabase::open.
该连接名称是在应用程序范围内定义的.因此,如果您调用addDatabase每个使用它的对象,您将更改QSqlDatabase使用相同连接名称的所有对象,并使所有对它们有效的查询无效.
您引用的第一个代码示例显示了如何正确地取消关联连接名称,确保:
QSqlQuery都是QSqlDatabase通过调用关闭数据库之前分离的QSqlQuery::finish(),当QSqlQuery对象超出范围时,这是自动的,QSqlDatabase具有相同连接名称的都是close()d QSqlDatabase::removeDatabase(close()当QSqlDatabase对象超出范围时也会自动调用).创建QSqlDatabase时,根据您是希望连接在应用程序生存期(1)或仅在需要时(2)保持打开,您可以:
将单个QSqlDatabase实例保存在一个单独的类中(例如,在主窗口中),并在需要它的其他对象中使用它,方法是QSqlDatabase直接传递或只传递传递给的连接名称QSqlDatabase::database以获取QSqlDatabase实例.QSqlDatabase::database用于从其名称中QHash检索a QSqlDatabase,因此它可能比QSqlDatabase在对象和函数之间直接传递对象慢得多,如果使用默认连接,则甚至不必在任何地方传递任何内容,只需在QSqlDatabase::database()没有任何参数的情况下调用.
// In an object that has the same lifetime as your application
// (or as a global variable, since it has almost the same goal here)
QSqlDatabase db;
// In the constructor or initialization function of that object
db = QSqlDatabase::addDatabase("QSQLDRIVER", "connection-name");
db.setHostname(...);
// ...
if(!this->db.open()) // open it and keep it opened
{
// Error handling...
}
// --------
// Anywhere you need it, you can use the "global" db object
// or get the database connection from the connection name
QSqlDatabase db = QSqlDatabase::database("connection-name");
QSqlQuery query(db);
Run Code Online (Sandbox Code Playgroud)配置QSqlDatabase一次,打开它来测试参数是否正确,然后抛弃实例.连接名称仍可在任何位置访问,但必须重新打开数据库:
{
// Allocated on the stack
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLDRIVER", "connection-name");
db.setHostname(...);
// ...
if(!this->db.open()) // test the connection
{
// Error handling
}
// db is closed when it goes out of scope
}
{
// Same thing as for (1), but by default database() opens
// the connection if it isn't already opened
QSqlDatabase db = QSqlDatabase::database("connection-name");
QSqlQuery query(db);
// if there is no other connection open with that connection name,
// the connection is closed when db goes out of scope
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,请注意您不应显式关闭数据库,因为您可以以可重入的方式使用相同的数据库连接(例如,如果函数A使用连接并调用也使用该连接的B).如果B在将控制权返回给A之前关闭了连接,那么A的连接也将被关闭,这可能是一件坏事.
| 归档时间: |
|
| 查看次数: |
42705 次 |
| 最近记录: |