返回首页

简介
建立一个数据库连接时,大家都知道,它可以是一个耗时的过程。因此,使用连接池的原因主要由于特定过程的延迟。连接池拥有连接捆绑,它永远不会被释放??除非池关闭。在一个连接池的设计,重要的是要引入一个抽象层,这将允许不同类型的连接,甚至不同类型的池。这样做的主要方式将介绍几个模式。所有的模式介绍[1]和总结[1]以下报价。抽象工厂
无需指定它们具体的类相关或依赖对象的家庭提供一个接口。{S0}
使用抽象工厂模式时,系统应独立,其产品是如何建立,组成和代表;系统应配置多个系列产品之一;相关的产品对象的家庭是设计用来在一起,你需要执行此约束,或你想提供一类产品库,和你想揭示只是它们的接口,而不是它们的实现。辛格尔顿
确保一个类只有一个实例,并提供一个访问它的全局来看。{S1}
使用Singleton模式时,必须有一个类的一个实例,它必须从一个众所周知的访问点,或唯一的实例时,应分分级扩展的客户,和客户应能使用一个扩展的实例,而无需修改其代码。工厂方法
定义用于创建对象的接口,但是让子类决定实例化哪一个类。工厂方法使一个类的实例化推迟到子类。{S2}
使用工厂方法模式,当一个类无法预料的类的对象,就必须创造一个类希望它的子类来指定创建或类委托责任几个帮手子类的对象,您要本地化其中帮手子类知识是委托。适配器
一个类的接口转换成客户期望的另一个接口。适配器允许类的工作在一起,不能否则由于不兼容的接口。
使用适配器模式,当您要使用现有的类,接口不匹配,你需要一个,你要创建一个可重用的类无关的或意外类的合作,就是不类一定兼容接口或(对象适配器),你需要使用一些现有的子类,但它是不切实际的,以适应分级每一个分它们的接口。对象适配器可以适应它的父类的接口。池的建设
通过使用这些模式,它可以将它们结合起来,得到一个设计,适合连接池的问题。这种模式被命名为池和一般[2]中描述。 CPool和CResource都是摘要。它们被用来使一个抽象层,这将使它可以重用不同的连接和CPoolFactory点看到,甚至不同的池连接池。具体的水平达到一个级别时。这个级别拥有的每一个抽象的对象的实施。
CPoolFactory是单身[1],它总是返回一个类型CPool的对象。 CPool将总是返回一个类型CResource的对象。这两个对象的初始化是在混凝土层,因此,它是由抽象层隐藏客户端。这给了我们重用的好处,而不是重新实现,因为它是只需要做出新的CConnectionAdapter实施,当连接到另一个数据库。当做到这一点,这是必要的,以确保该池实例化正确的连接??,但很容易。该接口还决定,它返回一个CResource。这意味着,新的实施必须实现它,以防止违反派生的合同。因此,它是只需要以前的实现是在池中创建的变化,因为这两种方案的使用CResource抽象??没有在客户端改变。在C语言实现
创建池时,它从数据库中提取的初始大小和创建的连接的初始数目。这是所有做CConnectionPool类的构造函数。

CConnectionPool::CConnectionPool()

{

	m_pool.clear();

	m_initSize = 0;

	long connstr = 0;



	CRegistryFacade *registry = new CRegistryFacade;

	registry->getKeyFromRegistry("InitSize", &connstr);

	if (0 == connstr)

	{

		registry->setKeyToRegistry("InitSize", "10");

		registry->getKeyFromRegistry("InitSize", &connstr);

	}

	delete registry;

	m_initSize = connstr;

	for (int i=0; i<m_initSize; i++)

	{		

		CConnectionAdapter * resource = new CConnectionAdapter;

		resource->setInUse(false);

		m_pool.push_back(resource);		

	}

}

CConnectionPool类有一种特殊的方法称为CConnectionPool::findNewConnection(),用于寻找新的可用连接的bool和使用的方法是由CConnectionPool:收购()方法。{C}
连接实现与CConnectionPool公布:收购()和CConnectionPool:释放(CResource * RES)方法。这些方法也通过抽象层访问,可以发现在CPool类。
CResource* CConnectionPool::aquire()

{

	CResource * resource = NULL;

	if (NULL == (resource = findNewConnection())) {

		resource = new CConnectionAdapter;

		m_pool.push_back(resource);

	}		

	return resource;

}



void CConnectionPool::release(CResource* res)

{

	bool found = false;

	list<CResource*>::iterator ite;

	ite=m_pool.begin();



	while(ite!=m_pool.end() && !found) {	

		CResource* entry = *ite;

		if (entry->operator == (*res)) {

			CConnectionAdapter *adapter = 

				dynamic_cast<CConnectionAdapter*>(entry);	

			adapter->setInUse(false);

			found = true;

		}



		ite++;

	}	

}

ADO连接封装在CC​​onnectionAdapter类。这个类的主要职责是保持连接,但它拥有一个布尔值,它告诉它是否在使用或不和他人之间的独特标识符,如其他信息。
CConnectionAdapter::CConnectionAdapter()

{

	CoInitialize(NULL);



	char* connstr = NULL;

	CRegistryFacade *registry = new CRegistryFacade;

	registry->getKeyFromRegistry("ConnectionString", &connstr);

	if (NULL == connstr || 0 == strlen(connstr))

	{

                //Failed to retrieve the connection string

                //Write default settings to the registry and use them

		registry->setKeyToRegistry

			("ConnectionString", "DATABASE=db;DSN=dsn;UID=sa;PWD=sa");

		

		if (NULL != connstr) {

			free(connstr);

			connstr = NULL;

		}



		registry->getKeyFromRegistry("ConnectionString", &connstr);

	}

	delete registry;



	m_connection.CreateInstance(__uuidof(Connection)); 

	m_connection->CursorLocation = adUseServer; 

	m_connection->Open(	connstr, L"", L"", adConnectUnspecified);	

	

	m_currentlyUsed = true; 

	

	CoCreateGuid (&m_id);

}

创建的CConnectionAdapter类的实例时,它从注册表中获取连接字符串(目前未加密!),建立连接和设置的唯一标识符。这个类有一个CConnectionAdapter:getConnection()方法,这给当前连接的指针。使用pool
使用此连接池时,它提供了一个框的使用出来,在那里,如连接字符串和的初始大小设置存储在注册表中。它还提供了创建基于这个库提供的抽象层的另一个连接池的可能性。在这种方式,它有可能使一个连接池,它支持Oracle连接以及如果需要的话。
//An instance of the pool factory has to be achieved

CPoolFactory *factory = CPoolFactory::getPoolFactory(); 

//Get an instance of the pool

CPool *pool = factory->getPool();

//Retrieve a connection from the pool

CResource *res = NULL;

res = pool->aquire();

//Release the connection when it is no more needed 

pool->release(res);

请注意该库是基于Microsoft数据访问组件(MDAC)。 CConnectionAdapter类封装在所有MDAC独立实施。参考文献
[1]设计模式:可重复使用的面向对象的软件
埃里希伽马,理查德头盔,拉尔夫约翰逊,Vissides约翰
艾迪生韦斯利,1995年
ISBN:0-201-63361-2的元素[2]面向模式的软件体系结构
第一卷。 3:
资源管理方式的迈克尔基歇尔,耆那教Prashant
WILEY,1995年10月
ISBN:0-470-84525-2历史第一,2007年1月:战后初期

回答

评论会员:会员2480572 时间:2011/12/07
CPoolFactory:CPoolFactory()
{
m_pool =新CConnectionPool
}

CPoolFactory:〜CPoolFactory()
{
m_pool =新CConnectionPool
删除m_pool;
m_pool = NULL;
}
评论会员:Jessn 时间:2011/12/07
我不知道你的问题是什么...

CPoolFactory仅是一个接口!它应该被用来作为一个接口,这意味着它可能不包含任何实现。接口是保证合同将会实现,当实现一个特定的工厂。这是为什么类没有任何构造函数或析构函数的原因,它仅包含纯虚方法。

/ *接口* /
类DATABASE_API CPoolFactory
{
市民:
虚拟CPool * getPool()= 0;
}

当使用的CPoolFactory类,因此,有必要使一个类从它继承。特定类必须包含所需的实施。

/ *执行* /
ADOADAPTER_API CADOPoolFactory类:公共CPoolFactory
{
市民:
CPool * getPool()
}
心连心

-
JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/修改日(星期一),3月31日,2008年12:58 PM
评论会员:会员2480572 时间:2011/12/07
我的问题是,在Pooling.cpp,构造函数和析构函数分配CConnectionPool,

为什么都分配一个CConnectionPool,但不会释放呢?{​​BR}
我还以为是一个错误,m_pool需要在析构函数删除。
(请原谅我的池英)

/ / Pooling.cpp
CPoolFactory:CPoolFactory()
{
m_pool =新CConnectionPool
}

CPoolFactory:〜CPoolFactory()
{
m_pool =新CConnectionPool
}
评论会员:Jessn 时间:2011/12/07
。哦,你是正确的,我有另外一个模块,这就是为什么implemenation

CPoolFactory:〜CPoolFactory()
{
 0;(m_pool)
删除m_pool;
}

请在此URL的框架更完整版本的外观和从该网址下载,如果你觉得它有用。
在这里下载[

-
JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/
评论会员:基思沃登 时间:2011/12/07
似乎有点过于复杂,它实现什么。为了同样的目的,我已经实现一个系统,但只创建连接,在需要的时候自动释放他们时不使用15分钟。我还可以嵌入在一个单独的类所有的get和免费的代码,所以我只需要一行代码(析构函数不自由,所以我不记得做)。
评论会员:Jessn 时间:2011/12/07
这听起来像你已经创建了一个对象,工程一拉,只是时间的事件实现智能指针。纠正我,如果我对这个错误。

类MyConnection的{
市民:
MyConnection的()
{
/ /创建连接
}
〜MyConnection的()
{
/ / destroyes连接
}
/ / ...更多的惊喜... ...
  ;ADODB::_ConnectionPtr m_pConnection
}

当使用这个类是一个参考的实例,你将有智能指针"效果"。当实例失控的范围,它是全自动删除连接就会被销毁。你只可以肯定,这是不应该用整个生命周期的方法或对象边界连接。

{
MyConnection的MyObj中;
/ /这里的东西与MyObj中...
}
/ / MyObj中全自动破坏这里的

其次,使用池的原因仍然是因为缓慢实现资源。上面介绍的方法,不解决这个问题,你必须使用一个游泳池。
什么那么数据源(如ODBC等),往往有一个隐含的游泳池,可你为什么没有在这方面的任何性能问题的原因。
- 修改5:59星期二一月九日,2007年
- 修改6:00星期二一月九日,2007年
- 修改2:37星期四一月十一日,2007年

-
JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/
评论会员:BadJerry 时间:2011/12/07
干得好 - 你还跟发布您的工作吗?

评论会员:Jessn 时间:2011/12/07

你可以找到一个完整的连接池库实现在下面的网址。

http://jessn.blogspot.com/2007/04/release-of-connection-pool-lib.html

不久,您将能够找到一个库,可用于记录以及使用。这也将是从我的博客

HTH



-
JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/
评论会员:Motorcure 时间:2011/12/07

我下载库中,但我想不使用注册表来保存连接字符串,你可以发布的源代码

顺便说一句:??我怎样才能修改连接字符串,我总是在工厂> getPool(),为什么execption BR}
Motorcure @


- 修改,2007年11月2日21点58日(星期五)

你受苦了,但为什么
评论会员:?Jessn 时间:2011/12/07
来源是巨大的。我的意图是,接口开放,但没有实施。无论如何,我会改变的设计,这将允许其他实现存储连接字符串。通过这种方式,将有可能存储需要的地方,只要连接字符串,因为它是由本人或由第三方实施。我会尽快让这些变化。请看看我的博客更新,在不久的将来。我会在URL的地方更新如下。

http://jessn.blogspot.com/2007/04/release-of-connection-pool-lib.html

> containts默认连接字符串
>值是明文写在名为
文件>"regvalues​​.txt",这很容易可以修改
>并粘贴到注册表中。

您在注册表中进入一个新的连接字符串和改变加密标志为零。文件是存储(程序文件夹?)与初始值存储到注册表注册表项的名称。

请仔细考虑您选择存储连接字符串。最安全的地方实际上是注册表。

心连心

- 4:50(星期四)11月8日修改,2007年
- 4:52(星期四)11月8日修改,2007年

JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/
评论会员:Jessn 时间:2011/12/07
我刚才已经做了一些变化,这将使得它可以存储到另外一个地方比注册表设置。我提出了相关的代码,这并不存储到一个单独的DLL。我已要求该DLL"Settings.dll",它是动态加载的。 DLL的名字存储到Win.ini文件。



所有你所要做的的是一个类似的DLL,其中包含一个导出类,来自CPoolSettings类(PoolSettings.h),并确保您的DLL具有相同的入口点。

/ /必需的入口点
MYEXPORT_API无效的EntryPoint()
{

返回static_castlt;无效* GT(新CRegistryFacade);}

连接字符串存储在注册表中,你会发现在以下注册表项

[HKEY_LOCAL_MACHINE \ SOFTWARE \尼尔森\ ConnectionPool]
对不起,等待的时间,但我已经有点紧围绕圣诞节和新年。
心连心
杰斯

-
JESS尼尔森,学士
安全分析

http://jessn.blogspot.com/

修改日(星期二),1月22日,2008上午11点51分34秒