Qt:类中的QSqlDatabase对象(如何声明?)

Qt:类中的QSqlDatabase对象(如何声明?),第1张

概述我正在尝试创建一个应该处理来自sqlite数据库的所有数据的类.但是,我对QT和C很新,并且想知道类中数据库对象声明.我可能需要一些关于我在做什么是对错以及通常应该或可以做什么的提示.我的目标是为类创建一个QSql Database并将其用于类中的每个函数. 目前,我有以下代码: main.cpp中 #include "mainwindow.h"#include "database.h"#i 我正在尝试创建一个应该处理来自sqlite数据库的所有数据的类.但是,我对QT和C很新,并且想知道类中数据库对象的声明.我可能需要一些关于我在做什么是对错以及通常应该或可以做什么的提示.我的目标是为类创建一个Qsql Database并将其用于类中的每个函数.

目前,我有以下代码:

main.cpp中

#include "mainwindow.h"#include "database.h"#include <QApplication>int main(int argc,char *argv[]){    QApplication a(argc,argv);    Database db;    MainWindow w;    if(db.createStructure())    {        w.show();    }    return a.exec();}

database.h

#ifndef DATABASE_H#define DATABASE_H#include <QObject>#include <QsqlDatabase>class Database : public QObject{    Q_OBJECTpublic:    explicit Database(QObject *parent = 0);    // FUNCTIONS    bool createStructure();signals:public slots:private:    // VARIABLES    QsqlDatabase m_db;    // FUNCTIONS    bool open();    voID close();    bool transaction();    bool commit();};#endif // DATABASE_H

database.cpp

#include "database.h"#include <QCoreApplication>#include <QsqlDatabase>#include <Qsqlquery>#include <QsqlError>#include <QList>Database::Database(QObject *parent) :    QObject(parent){    m_db = QsqlDatabase::addDatabase("QsqlITE");    m_db.setHostname("localhost");    m_db.setDatabasename(QCoreApplication::applicationDirPath() + "/events.db");}// PRIVATEbool Database::open(){    return m_db.open();}voID Database::close(){    return m_db.close();}bool Database::transaction(){    return m_db.transaction();}bool Database::commit(){    return m_db.commit();}// PUBliCbool Database::createStructure(){    bool prepared;    QList<QString> commands;    commands.append("CREATE table...;");    commands.append("CREATE table...;");    commands.append("CREATE table...;");    if (!Database::open())    {        return false;    }    else    {        if (!Database::transaction())        {            Database::close();            return false;        }        else        {            foreach(QString command,commands)            {                Qsqlquery query;                prepared = query.prepare(command);                if(!prepared)                {                    if (!Database::commit())                    {                        Database::close();                        return false;                    }                    else                    {                        Database::close();                        return false;                    }                }                else                {                    if(!query.exec())                    {                        if (!Database::commit())                        {                            Database::close();                            return false;                        }                        else                        {                            Database::close();                            return false;                        }                    }                }            }            if (!Database::commit())            {                Database::close();                return false;            }            else            {                Database::close();                return true;            }        }    }}

这段代码正在运行.

但是,QsqlITE数据库不是一次添加到m_db对象,而是每次调用类中的函数时,因为……

Database::Database(QObject *parent) :    QObject(parent){    m_db = QsqlDatabase::addDatabase("QsqlITE");    m_db.setHostname("localhost");    m_db.setDatabasename(QCoreApplication::applicationDirPath() + "/events.db");}

…每次执行代码块.
当前的默认连接只是被替换,因为新的连接是相同的,这对程序没有任何影响,但它看起来不像一个简洁的解决方案.

所以我试着用一个声明函数替换这个代码块,我可以从main.cpp调用一次…

main.cpp中

int main(int argc,argv);    Database db;    MainWindow w;    db.declare(“QsqlITE”,“localhost”,QCoreApplication::applicationDirPath() + "/events.db");    if(db.createStructure())    {        w.show();    }    return a.exec();}

database.cpp

voID Database::declare(QString driver,QString host,QString path){    m_db = QsqlDatabase::addDatabase(driver);    m_db.setHostname(host);    m_db.setDatabasename(path);}

…但是m_db对象的值当然只能在declare-function中使用,而不能用于我之后调用的其他函数.

我对解决方案的最佳猜测是在main.cpp中声明QsqlDatabase并将其提供给它应该调用的函数:

main.cpp中

int main(int argc,argv);    QsqlDatabase qdb = QsqlDatabase::addDatabase("QsqlITE");    qdb.setHostname("localhost");    qdb.setDatabasename(QCoreApplication::applicationDirPath() + "/events.db");    Database db;    MainWindow w;    if(db.createStructure(qdb))    {        w.show();    }    return a.exec();}

database.cpp

bool Database::open(QsqlDatabase qdb){    return qdb.open();}voID Database::close(QsqlDatabase qdb){    return qdb.close();}bool Database::transaction(QsqlDatabase qdb){    return qdb.transaction();}bool Database::commit(QsqlDatabase qdb){    return qdb.commit();}bool Database::createStructure(QsqlDatabase qdb){    bool prepared;    QList<QString> commands;    commands.append("CREATE table...;");    commands.append("CREATE table...;");    commands.append("CREATE table...;");    if (!Database::open(qdb))    {        return false;    }    else    {        if (!Database::transaction(qdb))        {            Database::close(qdb);            return false;        }        else        {            foreach(QString command,commands)            {                Qsqlquery query;                prepared = query.prepare(command);                if(!prepared)                {                    if (!Database::commit(qdb))                    {                        Database::close(qdb);                        return false;                    }                    else                    {                        Database::close(qdb);                        return false;                    }                }                else                {                    if(!query.exec())                    {                        if (!Database::commit(qdb))                        {                            Database::close(qdb);                            return false;                        }                        else                        {                            Database::close(qdb);                            return false;                        }                    }                }            }            if (!Database::commit(qdb))            {                Database::close(qdb);                return false;            }            else            {                Database::close(qdb);                return true;            }        }    }}

是否有可能以某种方式在类中存储可重用的QsqlDatabase对象?如果是这样,怎么样?
真的很感谢你的帮助!

编辑1

从我正在使用函数的设计器创建的一些代码.

mainwindows.cpp

voID MainWindow::on_pushbutton_24_clicked(){    Database db;    bool b = db.createStructure();    QMessageBox::information(this,"test",QString(b));}
解决方法 我会坚持你原来的代码来解释.

免责声明:我没有编译我的任何建议,如果有语法错误,请原谅我.

首先,你可能正在寻找的是Singleton Pattern(我不再那么喜欢了,但为了你的目的,人们可以说它可以被认为是合适的):

您必须在类定义中包含以下内容:

class Database : public QObject{    Q_OBJECTpublic:    static Database* instance();private:    static Database* m_instance;    Database();    ~Database() {}; // it can be necessary to have this public in some cases,if                     // you ever get a linker error related to deletion,this is                     // probably the reason.public:     // FUNCTIONS    ...};

以及.cpp文件中的以下内容:

// init singleton pointer to NulLDatabase* Database::m_instance = NulL;Database* Database::instance(){    if( !m_instance )    {        m_instance = new Database();    }    return m_instance;}

然后,您可以使用例如访问该单例

if( Database::instance()->createStructure() ){    w.show();}

这是做什么的?在程序开始时,该行

Database* Database::m_instance = NulL;

将m_instance变量初始化为NulL.第一次调用Database :: instance()时,它意识到m_instance仍为NulL并创建一个新对象并使m_instance指向该对象.从那时起,将始终返回指向该对象的指针,但不会再创建数据库对象.

在createStructure()函数中,即使出现错误,也可以提交数据库.通常的过程是在成功时commit()并在失败时回滚().
在修复之前,请务必阅读下一点:

我建议的第三件事是,每当你看到多次出现相同的行时,就会习惯于怀疑.这通常会引发子功能.

我在说

Database::close();return false;

看看我如何通过引入另一个方法重写你的createStructure()方法,并将else {}留在不需要的地方:

bool Database::createStructure(){    QStringList commands;    commands.append("CREATE table...;");    commands.append("CREATE table...;");    commands.append("CREATE table...;");    if (!Database::open()) return false;    // at this point you can be sure the database is open    if (!Database::transaction())    {         Database::close();        return false;    }    // at this point you can be sure the database is open and a transaction was started    if (!Database::executeCommands(commands))    {        // an error occurred - we need to rollback what we dID so far        Database::rollback();        Database::close();        return false;    }    // everything was executed properly,but the transaction is still active    // => commit the changes we've made    bool committed = Database::commit();    // no matter if the commit was successful or not,close the database,// then return the result we've stored    Database::close();    return committed;}bool Database::executeCommands(const QStringList& commands){    // This method simply executes the querIEs and is relIEved from    // transaction-related code.    foreach(QString command,commands)    {        Qsqlquery query;        bool prepared = query.prepare(command);        if(!prepared) return false;        if(!query.exec()) return false;            }    return true;}

这可以进一步重构,它只是使代码更容易遵循的一个例子,因此通常不易出错.

总结

以上是内存溢出为你收集整理的Qt:类中的QSqlDatabase对象(如何声明?)全部内容,希望文章能够帮你解决Qt:类中的QSqlDatabase对象(如何声明?)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1155027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存