有些类也需要计划生育--单例模式

来源:互联网 发布:王自如 罗永浩 知乎 编辑:程序博客网 时间:2024/04/28 08:48

数据库操作,有关数据库管理的问题总结:


第一次设计:




简单介绍:


代码:

#ifndef DBCONNECTION_H#define DBCONNECTION_H#include <QString>#include <QSql> #include <QSqlDatabase> #include <QSqlQuery>class DBConnection{public:DBConnection();bool OpenDatabase();void selectFromTable(QString );void setDNS(QString);void setUserName(QString);void setUserPassword(QString);void setPortId(int);QString getDNS();QString getUserName();QString getUserPassword();int getPortId();~DBConnection();private:QString m_DNS;QString m_userName;QString m_userPassword;int m_portId;QSqlDatabase m_sqlDatabase;};#endif // DBCONNECTION_H#include "DBConnection.h"DBConnection::DBConnection():m_DNS(""),m_portId(1433),m_userName("sa"),m_userPassword("jiachangbin"){}DBConnection::~DBConnection(){m_sqlDatabase = QSqlDatabase::addDatabase("QODBC", "connectionSQL");m_DNS = "";m_sqlDatabase.database(m_DNS);m_sqlDatabase.setUserName(m_userName);m_sqlDatabase.setPassword(m_userPassword);m_sqlDatabase.setPort(m_portId);}bool DBConnection::OpenDatabase(){if (m_sqlDatabase.open()){return true;}return false;}void DBConnection::setDNS( QString dns){m_DNS = dns;}void DBConnection::setUserName( QString userName){m_userName = userName;}void DBConnection::setUserPassword( QString userPassword){m_userPassword = userPassword;}void DBConnection::setPortId( int portID){m_portId = portID;}QString DBConnection::getDNS(){return m_DNS;}QString DBConnection::getUserName(){return m_userName;}QString DBConnection::getUserPassword(){return m_userPassword;}int DBConnection::getPortId(){return m_portId;}void DBConnection::selectFromTable( QString selectStr){QSqlQuery sqlQuery(selectStr);while (sqlQuery.next()){QString country = sqlQuery.value(0).toString();}}#include <QtCore/QCoreApplication>#include "DBConnection.h" int main(int argc, char *argv[]){QCoreApplication a(argc, argv);DBConnection *pDBConnection = new DBConnection();if (pDBConnection->OpenDatabase()){pDBConnection->selectFromTable("select * from ");}return a.exec();}

缺点:

缺点:如果数据库发生改变,整个类就要改动
数据库只有打开没有关闭
链接数据库和使用数据库在一起,耦合度较高
数据库参数设置默认值太过死板,如果发生改变和默认值不同,要么修改代码,要么每次都要设置参数
数据库连接类对外开发,谁都可以试试数据库连接

改进需求:


改进介绍:


单例模式介绍:


代码:


#ifndef SYSINIMANAGE_H#define SYSINIMANAGE_H#include <QSettings> class sysIniManage{public:sysIniManage();static void createIniFile();~sysIniManage();private:QString m_path;};#endif // SYSINIMANAGE_H#include "sysIniManage.h"//#definesysIniManage::sysIniManage(){QSettings settings("Moose Soft", "Clipper");}sysIniManage::~sysIniManage(){}void sysIniManage::createIniFile(){}#ifndef DBCONNECTPOOL_H#define DBCONNECTPOOL_H#include <QtSql>#include <QQueue>#include <QString>#include <QMutex>#include <QMutexLocker>#include "sysIniManage.h"class DBConnectPool{public:static QSqlDatabase openConnection();                 // 获取数据库连接static void closeConnection(QSqlDatabase connection); // 释放数据库连接回连接池static void release(); // 关闭所有的数据库连接~DBConnectPool();private:DBConnectPool();static DBConnectPool& getInstance();//单例模式DBConnectPool(const DBConnectPool &other);//拷贝构造DBConnectPool& operator=(const DBConnectPool &other);//操作符重载QSqlDatabase createConnection(const QString &connectionName); // 创建数据库连接QQueue<QString> usedConnectionNames;   // 已使用的数据库连接名QQueue<QString> unusedConnectionNames; // 未使用的数据库连接名private:static QMutex mutex;static QWaitCondition waitConnection;static DBConnectPool *instance;};#endif // DBCONNECTPOOL_H#include "DBConnectPool.h"QMutex DBConnectPool::mutex;QWaitCondition DBConnectPool::waitConnection;DBConnectPool* DBConnectPool::instance = NULL;DBConnectPool::DBConnectPool(){}DBConnectPool::~DBConnectPool(){// 销毁连接池的时候删除所有的连接foreach( QString connectionName, usedConnectionNames ){QSqlDatabase::removeDatabase(connectionName);}foreach( QString connectionName, unusedConnectionNames ){QSqlDatabase::removeDatabase(connectionName);}}DBConnectPool& DBConnectPool::getInstance(){if ( NULL == instance ){QMutexLocker locker(&mutex);if ( NULL == instance){instance = new DBConnectPool();}}return *instance;}QSqlDatabase DBConnectPool::openConnection(){DBConnectPool & pool = DBConnectPool::getInstance();QString connectionName;QMutexLocker locker( &mutex );// 已创建连接数int connectionCount = pool.unusedConnectionNames.size() + pool.usedConnectionNames.size();// 如果连接已经用完,等待 waitInterval 毫秒看看是否有可用连接,最长等待 maxWaitTime 毫秒for ( int i = 0; i < pool.maxWaitTime&& pool.unusedConnectionNames.size() == 0 && connectionCount == pool.maxConnectionCount; i += pool.waitInterval) {waitConnection.wait(&mutex, pool.waitInterval);// 重新计算已创建连接数connectionCount = pool.unusedConnectionNames.size() + pool.usedConnectionNames.size();}if (pool.unusedConnectionNames.size() > 0) {// 有已经回收的连接,复用它们connectionName = pool.unusedConnectionNames.dequeue();} else if (connectionCount < pool.maxConnectionCount) {// 没有已经回收的连接,但是没有达到最大连接数,则创建新的连接connectionName = QString("Connection-%1").arg(connectionCount + 1);} else {// 已经达到最大连接数qDebug() << "Cannot create more connections.";return QSqlDatabase();}// 创建连接QSqlDatabase db = pool.createConnection(connectionName);// 有效的连接才放入 usedConnectionNamesif (db.isOpen()) {pool.usedConnectionNames.enqueue(connectionName);}return db;}QSqlDatabase DBConnectPool::createConnection( const QString &connectionName ){// 连接已经创建过了,复用它,而不是重新创建if (QSqlDatabase::contains(connectionName)) {QSqlDatabase db1 = QSqlDatabase::database(connectionName);if (testOnBorrow) {// 返回连接前访问数据库,如果连接断开,重新建立连接qDebug() << "Test connection on borrow, execute:" << testOnBorrowSql << ", for" << connectionName;QSqlQuery query(testOnBorrowSql, db1);if (query.lastError().type() != QSqlError::NoError && !db1.open()){qDebug() << "Open datatabase error:" << db1.lastError().text();return QSqlDatabase();}}return db1;}// 创建一个新的连接QSqlDatabase db = QSqlDatabase::addDatabase(databaseType, connectionName);db.setHostName(hostName);db.setDatabaseName(databaseName);db.setUserName(username);db.setPassword(password);if (!db.open()) {qDebug() << "Open datatabase error:" << db.lastError().text();return QSqlDatabase();}return db;}void DBConnectPool::closeConnection( QSqlDatabase connection ){DBConnectPool& pool = DBConnectPool::getInstance();QString connectionName = connection.connectionName();// 如果是我们创建的连接,从 used 里删除,放入 unused 里if (pool.usedConnectionNames.contains(connectionName)) {QMutexLocker locker(&mutex);pool.usedConnectionNames.removeOne(connectionName);pool.unusedConnectionNames.enqueue(connectionName);waitConnection.wakeOne();}}void DBConnectPool::release(){QMutexLocker locker(&mutex);delete instance;instance = NULL;}#ifndef DBCONNECTION_H#define DBCONNECTION_H#include <QString>#include <QSql> #include <QSqlDatabase> #include <QSqlQuery>#include "DBConnectPool.h"class DBConnection{public:DBConnection();bool OpenDatabase();void selectFromTable(QString );~DBConnection();private:QSqlDatabase m_sqlDatabase;};#endif // DBCONNECTION_H#include "DBConnection.h"DBConnection::DBConnection(){m_sqlDatabase = DBConnectPool::openConnection();}DBConnection::~DBConnection(){DBConnectPool::closeConnection(m_sqlDatabase);}bool DBConnection::OpenDatabase(){if (m_sqlDatabase.open()){return true;}return false;}void DBConnection::selectFromTable( QString selectStr){QSqlQuery sqlQuery(selectStr, m_sqlDatabase);if (sqlQuery.isValid()){while (sqlQuery.next()){QString country = sqlQuery.value(0).toString();}}}#include <QtCore/QCoreApplication>#include "DBConnection.h"#include "DBConnectPool.h"int main(int argc, char *argv[]){QCoreApplication a(argc, argv);DBConnection *pDBConnection = new DBConnection();if (pDBConnection->OpenDatabase()){pDBConnection->selectFromTable("select * from ");}pDBConnection->~DBConnection();DBConnectPool::release();return a.exec();}

缺陷:


改进需求:


改进计划:


0 0