我有Qt应用程序,它有DatabaseService单例,只有一个QSqlDatabase实例,还有许多线程应该使用QSqlDatabase实例,当某些线程使用QSqlDatabase实例时,互斥锁住了。但我知道这不是这个任务的最佳模式。
应该在这里使用某种DB连接池还是类似的东西?以及如何在Qt中实现它?
请提供一些例子。
UPD:
如果一个类的实例将已为,则该类将有多个实例:
.cpp:
//...
QFuture<QMap<QString, QString>> future = QtConcurrent::run(DatabaseService::executeQuery, sqlCommand);
future.waitForFinished();
//...DatabaseService:
.h:
class DatabaseService
{
public:
//...
static QMap<QString, QString> executeQuery(QString command);
private:
static QThreadStorage<QSqlDatabase> mDatabasePool;
static QSqlDatabase getDatabase();
};.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;
}
//...UPD 2:
main.cpp:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer server;
server.listen(QHostAddress::Any, 1234);
return a.exec();
}没药。h:
class MyServer : public QTcpServer
{
Q_OBJECT
explicit MyServer(QObject *parent = 0);
~MyServer();
protected:
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
signals:
void stopAll();
};myserver.cpp:
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();
}我的客户:
class MyClient : public QObject
{
Q_OBJECT
public:
explicit MyClient(int socketDescriptor, MyServer *server);
~MyClient();
private:
QSslSocket* socket = NULL;
public slots:
void process();
}myclient.cpp:
void MyClient::process(){
//typical connection things
connect(this->socket, SIGNAL(encrypted()), this, SLOT(ready()));
}
void MyClient::ready(){
connect(socket,SIGNAL(readyRead()),this, SLOT(newData()));
}发布于 2017-11-16 08:39:16
我做了一个软件也使用数据库连接。我不对我的应用程序使用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中,worker QFuture位于libserver中。你可以用它作为参考。但我不确定我的设计是否适合你。
https://stackoverflow.com/questions/47322341
复制相似问题