QSqlDatabase&;的正确方法是什么;QSqlQuery?
我对手册感到困惑,我是否应该这样工作:QSqlDatabase&;的正确方法是什么;QSqlQuery?,database,qt,qt4,qtsql,Database,Qt,Qt4,Qtsql,我对手册感到困惑,我是否应该这样工作: { QSqlDatabase db = QSqlDatabase::addDatabase (...); QSqlQuery query (db); query.exec (...); } QSqlDatabase::removeDatabase (...); 正如文档所指出的,query或db将自动解构。 但这有效率吗 如果我在类中缓存db,如下所示: class Dummy { Dummy() { db = QSqlDataba
{
QSqlDatabase db = QSqlDatabase::addDatabase (...);
QSqlQuery query (db);
query.exec (...);
}
QSqlDatabase::removeDatabase (...);
正如文档所指出的,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;
};
有时我会看到如下警告:
QSqlDatabasePrivate::removeDatabase: connection 'BLABLA' is still in use, all queries will cease to work.
即使我没有调用
run()
QSqlDatabase和QSqlQuery都是围绕具体实现的轻量级包装,所以您的第一个示例也很好。如果在添加连接时提供名称,或使用默认数据库,则只需编写“QSqlDatabase db(name)”即可使数据库对象的开销非常小
removeDatabase相当于关闭文件(对于sqlite)或连接(对于ODBC/MySql/Postgres),因此这通常是程序终止时要做的事情。正如警告所说,您必须确保引用该数据库的所有数据库和查询对象都已被销毁,否则可能会发生不好的事情。使用
addDatabase
创建QSqlDatabase
对象或调用removeDatabase
时,您只是在关联或解除元组关联(驱动程序、主机名:端口、数据库名称、用户名/密码)设置为名称(如果未指定连接名称,则设置为默认连接名称)。SQL驱动程序已实例化,但只有在调用
QSqlDatabase::open
时才会打开数据库
该连接名称是在应用程序范围内定义的。因此,如果在使用该名称的每个对象中调用addDatabase
,则会更改使用相同连接名称的所有QSqlDatabase
对象,并使其上所有活动的查询无效
您引用的第一个代码示例演示了如何通过确保:
- 在通过调用
关闭数据库之前,所有QSqlQuery::finish()
都会从QSqlQuery
中分离,当QSqlDatabase
对象超出范围时,这是自动的QSqlQuery
- 调用
时,具有相同连接名称的所有QSqlDatabase::removeDatabase
都是QSqlDatabase
d(当close()
对象超出范围时,也会自动调用QSqlDatabase
)close()
QSqlDatabase
实例保存在单个类中(例如,在主窗口中),并通过直接传递QSQLDABASE
或仅传递给QSQLDABASE::database
以获取QSQLDABASE
实例的连接名称,在需要它的其他对象中使用它。QSQLDABASE::database
使用QHash
从其名称检索QSQLDABASE
,因此,它可能比在对象和函数之间直接传递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);
QSQLDABASE
一次,打开它以测试参数是否正确,然后丢弃实例。连接名称仍然可以在任何地方访问,但必须重新打开数据库:
{
// 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
}
在这种情况下,请注意不应显式关闭数据库,因为可以以可重入方式使用同一数据库连接的多个对象(例如,如果函数a使用连接并调用B,B也使用连接。如果B在将控制权返回给a之前关闭连接,则a的连接也将关闭,这可能是一件坏事)我发现指令必须严格按照下面的顺序运行,否则数据库连接或查询会出现问题。这在Qt5中有效
QSqlQueryModel *model = new QSqlQueryModel;
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(fileName);
if (db.isValid())
{
db.open();
if (db.isOpen())
{
QSqlQuery searchQuery(db);
searchQuery.prepare("SELECT * FROM myTable");
searchQuery.exec();
if(searchQuery.isActive())
{
model->setQuery(searchQuery);
sui->DBDisplay->setModel(model);
db.close();
} else {
qDebug() << "query is not active";
}
} else {
qDebug() << "DB is not open";
}
} else {
qDebug() << "DB is not valid";
}
QSqlQueryModel*model=新的QSqlQueryModel;
db=QSqlDatabase::addDatabase(“QSQLITE”);
db.setDatabaseName(文件名);
if(db.isValid())
{
db.open();
if(db.isOpen())
{
QSqlQuery搜索查询(db);
searchQuery.prepare(“从myTable中选择*);
searchQuery.exec();
if(searchQuery.isActive())
{
模型->设置查询(搜索查询);
sui->DBDisplay->setModel(model);
db.close();
}否则{
qDebug()我遇到了这个问题,在进行此调整后,我能够关闭调用QSqlDatabase::removeDatabase(QSqlDatabase::database(“database NAME”);