首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt中的DB连接池

问Qt中的DB连接池
EN

Stack Overflow用户
提问于 2017-11-16 05:34:23
回答 1查看 2.3K关注 0票数 1

我有Qt应用程序,它有DatabaseService单例,只有一个QSqlDatabase实例,还有许多线程应该使用QSqlDatabase实例,当某些线程使用QSqlDatabase实例时,互斥锁住了。但我知道这不是这个任务的最佳模式。

应该在这里使用某种DB连接池还是类似的东西?以及如何在Qt中实现它?

请提供一些例子。

UPD:

如果一个类的实例将已为,则该类将有多个实例:

.cpp:

代码语言:javascript
复制
//...

QFuture<QMap<QString, QString>> future = QtConcurrent::run(DatabaseService::executeQuery, sqlCommand);

future.waitForFinished();

//...

DatabaseService:

.h:

代码语言:javascript
复制
class DatabaseService
{
public:
    //...
    static QMap<QString, QString> executeQuery(QString command);

private:
    static QThreadStorage<QSqlDatabase> mDatabasePool;
    static QSqlDatabase getDatabase();

};

.cpp:

代码语言:javascript
复制
//...
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:

代码语言:javascript
复制
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyServer server;

    server.listen(QHostAddress::Any, 1234);

    return a.exec();
}

没药。h:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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();
}

我的客户:

代码语言:javascript
复制
class MyClient : public QObject
{
    Q_OBJECT
public:
    explicit MyClient(int socketDescriptor, MyServer *server);
    ~MyClient();

private:
    QSslSocket* socket = NULL;

public slots:
    void process();
}

myclient.cpp:

代码语言:javascript
复制
void MyClient::process(){
    //typical connection things
    connect(this->socket, SIGNAL(encrypted()), this, SLOT(ready()));
}

void MyClient::ready(){
    connect(socket,SIGNAL(readyRead()),this, SLOT(newData()));
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-16 08:39:16

我做了一个软件也使用数据库连接。我不对我的应用程序使用QThread,而是使用QFuture,线程将从全局线程池中获取(正常情况下,线程池的数量将是CPU线程的数量)。

当访问数据库时,每个池都有自己的QSqlDatabase。我使用QThreadStorage作为QSqlDatabase的存储。

代码语言:javascript
复制
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中。你可以用它作为参考。但我不确定我的设计是否适合你。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47322341

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档