我有Qt应用程序,它有<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="toggler_container">
<select name="select" id="aaa">
<option value="0">---</option>
<option value="1">AAA</option>
<option value="2">BBB</option>
</select>
<select name="select" id="bbb">
<option value="0">---</option>
<option value="1">AAA</option>
<option value="2">BBB</option>
</select>
<select name="select" id="ccc">
<option value="0">---</option>
<option value="1">AAA</option>
<option value="2">BBB</option>
</select>
</div>
单例,只有一个DatabaseService
实例,而且很多线程应该使用这个QSqlDatabase
实例,当一些线程使用实例时,mutex会被锁定QSqlDatabase
。但我明白这不是这项任务的最佳模式。
我应该在这里使用某种类型的数据库连接池还是这样的?我怎样才能在Qt中实现它?
请提供一些例子。
UPD:
一个实例已经的类有自己的线程,这个类会有多个实例:
的.cpp:
QSqlDatabase
DatabaseService:
·H:
//...
QFuture<QMap<QString, QString>> future = QtConcurrent::run(DatabaseService::executeQuery, sqlCommand);
future.waitForFinished();
//...
的.cpp:
class DatabaseService
{
public:
//...
static QMap<QString, QString> executeQuery(QString command);
private:
static QThreadStorage<QSqlDatabase> mDatabasePool;
static QSqlDatabase getDatabase();
};
UPD 2:
main.cpp中:
//...
QThreadStorage<QSqlDatabase> DatabaseService::mDatabasePool;
QSqlDatabase DatabaseService::getDatabase()
{
if(DatabaseService::mDatabasePool.hasLocalData()) {
return DatabaseService::mDatabasePool.localData();
} else {
auto database = QSqlDatabase::addDatabase("QPSQL", QUuid::createUuid().toString());
database.setHostName("hostName");
database.setDatabaseName("databaseName");
database.setUserName("user");
database.setPassword("password");
DatabaseService::mDatabasePool.setLocalData(database);
return database;
}
}
QMap<QString,QString> DatabaseService::executeQuery(QString command){
QSqlQuery query (DatabaseService::getDatabase());
query.exec(command);
//...
return result;
}
//...
myserver.h:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
server.listen(QHostAddress::Any, 1234);
return a.exec();
}
myserver.cpp:
class MyServer : public QTcpServer
{
Q_OBJECT
explicit MyServer(QObject *parent = 0);
~MyServer();
protected:
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
signals:
void stopAll();
};
myclient.h:
MyServer::MyServer(QObject *parent) : QTcpServer(parent)
{
}
MyServer::~MyServer(){
emit stopAll();
}
void MyServer::incomingConnection(qintptr socketDescriptor){
QThread* clientThread = new QThread;
MyClient *client = new MyClient(socketDescriptor, this);
client->moveToThread(clientThread);
connect(clientThread, SIGNAL(started()), client, SLOT(process()));
connect(client, SIGNAL(finished()), clientThread, SLOT(quit()));
connect(this, SIGNAL(stopAll()), client, SLOT(stopFromServer()));
connect(client, SIGNAL(finished()), client, SLOT(deleteLater()));
connect(clientThread, SIGNAL(finished()), clientThread, SLOT(deleteLater()));
clientThread->start();
}
myclient.cpp:
class MyClient : public QObject
{
Q_OBJECT
public:
explicit MyClient(int socketDescriptor, MyServer *server);
~MyClient();
private:
QSslSocket* socket = NULL;
public slots:
void process();
}
答案 0 :(得分:3)
我还使用数据库连接创建了一个软件。我不在我的应用程序上使用QThread但是使用QFuture并且线程将从全局线程池中获取(通常,线程池的数量将是CPU线程的数量)。
访问数据库时,每个池都有自己的QSqlDatabase。我使用QThreadStorage作为QSqlDatabase的存储。
static QThreadStorage<QSqlDatabase> mDatabasePool;
....
QSqlDatabase Db::getDatabase()
{
if(mDatabasePool.hasLocalData()) {
return mDatabasePool.localData();
} else {
auto database = QSqlDatabase::addDatabase(SQLDRIVERNAME[DBTYPE], QUuid::createUuid().toString());
mDatabasePool.setLocalData(database);
return database;
}
}
因此,只有在线程没有连接时才会创建数据库连接。
对于完整示例项目,您可以查看我的项目:https://github.com/apinprastya/sultan。数据库位于libdb内,而工作者QFuture位于libserver中。您可以将它用作参考。但我不确定我的设计是否适合你。