目前,我有以下代码:
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对象(如何声明?)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)