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

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


第一次设计:




简单介绍:


代码:

#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"

//#define

sysIniManage::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);

	// 有效的连接才放入 usedConnectionNames
	if (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();
}


缺陷:


改进需求:


改进计划:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值