王朝网络
分享
 
 
 

.net环境中数据库访问组件的应用

王朝c#·作者佚名  2008-05-19
宽屏版  字体: |||超大  

最近我写了一个.net环境下的C#动态链接库xmldb.dll。它仅包括一个XMLDBComponent类,这个类大大简化了数据库编程的工作量。举例来说,它可以执行一个sql查询,并以一个简单的调用方法把得到的数据转化成xml文档。

源代码包中包含三个工程文件。

● xmldblib建立库,xmldb.dll;

● xmldbtest是一个asp.net的测试程序;

● xmldbservice是一个web服务,它令使用不同机器和平台的用户都可以访问xmldb.dll;

除非特殊情况,样例代码都是用c#写的。

xmldbcomponent是用System.Data.OleDb 名字空间的类实现的。现在你仅使用一个类就可以在.net中完成所有的基本数据库工作,无需使用5个或更多的类。代价就是,你不能完全拥有.net框架类可给与的力量和控制。我不想要适应SQL sever而限制我的数据库,所以我不用System.Data.SqlClient 名字空间的类来构建自己的类,而宁愿用MS Access。System.Data.OleDb类不支持ODBC数据源是最糟糕的了。

代码仅在win2000,sql7和sql2000,以及MS Access数据库的环境中测试过。

简单的数据库访问

首先,我们得创建一个XMLDBComponent对象的实例。这是通过调用静态的方法CreateObject(),如下:

XMLDBLib.XMLDBComponent obj = XMLDBLib.XMLDBComponent.CreateObject(

"Provider=myProvider;Database=myDB;Server=myServer;" +

"User ID=me;Password=");

上面代码中的参数是连接字符串。对象创建之后,下面的代码会执行一个sql查询,然后将返回的数据存成一个文件。

System.Xml.XmlDocument doc = obj.GetXmlDocument(

"select ID, firstname, lastname, hiringdate " +

"from employee");

obj.Close();

// or call Release instead of Close:

// obj.Release();

if(doc==null)

{

String strError = obj.GetLastError();

// more error handling code

}

else

doc.Save("c:\temp\employee.xml");

}

Close()方法会关闭数据库连接,释放所有内部资源。如果你稍后还要用到XMLDBComponent对象就无需调用这个方法。即使你调用了Close(),在下一次使用对象的时候,它就知道如何自动的连接数据库。事实上,每次由于数据库出现错误而刷新数据库连接时,内部都会调用Close()方法。稍后我们会谈到Release()方法。

下面是展现上面代码返回数据的xml文件。

<XMLData>

<Record>

<ID>334</ID>

<firstname>Albert</firstname>

<lastname>Einstein</lastname>

<hiringdate>3/12/1999</hiringdate>

</Record>

<Record>

<ID>404</ID>

<firstname>Clint</firstname>

<lastname>Eastwood</lastname>

<hiringdate>12/21/2000</hiringdate>

</Record>

<Record>

<ID>536</ID>

<firstname>James</firstname>

<lastname>Bond</lastname>

<hiringdate>10/23/2002</hiringdate>

</Record>

<RecordCount>3</RecordCount>

<FieldCount>4</FieldCount>

</XMLData>

GetXmlDocument()方法从数据库中取得数据,并且创建输出文档对象。它出错时返回null。在输出的xml文档中,每一个记录都被<Record>元素所包含,记录的每一字段都是子元素。如果一个字段值是null,那么相应的子元素不会出现在输出文档中。sql查询中使用的字段名会作为字段元素的名字使用。如果其字段没有指明(比如select * from..),数据库中相应的字段名会被用为元素名。sql查询时,计数字段必须给出名字,比如select count(*) as total from employee。在xml文档的末尾,有两个元素<RecordCount> 和 <FieldCount> 显示了输出纪录集的大小。

GetXmlString()和GetXmlDocument() 除了输出的是字符串而不是文档对象外基本一样。这种方法在出错时其返回空字符串。而且,不会有由XMLDBComponent的问题引起的异常。你可以通过返回值来查错,GetLastError()返回最近错误的描述性信息。

线程安全性和对象池

所有在XMLDBComponent类中使用的静态方法都具有线程安全性,但类在对象级别不是线程安全的,这意味着你不能使用多线程同时访问对象。在多线程应用(如web服务器)中,有很多同时运行的线程。我们能在每一个新线程中创建一个单独的XMLDBComponent对象。但是,这并不是最有效的方法,因为并非所有的线程都在做与数据库有关的工作,我们要最大限度的利用已经存在的对象。

XMLDBComponent维护全局对象池,这令共享对象变得很容易。当你调用CreateObject方法时,它先查看全局对象池,看是否已有一个使用同样的连接字符串但未使用的对象。如果找到,就将它会被返回,无需再创建新的。如果你不再需要某个对象,就调用Release(),这样其他线程就可以重新使用它。注意,在对象的Release()被调用后,你不能再用它。

另外,在释放对象到对象池以前,你根本无需调用Close(),因为同样一个对象稍候就可能被再用。在程序末尾,你应调用静态方法CloseAll(),它将对全局对象池中全部未使用的对象调用Close方法。因此,只要你记得在使用一个对象之后释放它,CloseAll()会替你清除一切。

你不必和你创建的XMLDBComponent对象一直保持联系,只需调用GetID()就可以获得它的ID字符串。在程序的后部,你可以ID字符串为参数调用GetObject来获取你以前用过的那个对象。但如果你已经调用了Release(),就不能这样了。这个特性在你实现基于XMLDBComponent的WEB服务时非常有帮助,稍候你就会看到。

现在,.net框架类已支持数据库连接池。

在sql查询和存储过程中使用参数

除了从数据库中取得数据以外,你还可修改数据库中的纪录(插入,更新,或删除)。假设你有一个存储过程UpdateTotal,它有两个参数:字符串参数ID和整数型参数total,下面是一个调用这个过程的VB子程序。

Public Sub CallProcUpdateTotal( _

ByVal strConnect as String, ByVal strID as String, _

ByVal nTotal as Integer)

Dim obj as XMLDBLib.XMLDBComponent = _

XMLDBLib.XMLDBComponent.CreateObject(strConnect)

obj.AddParameter(strID)

obj.AddParameter(nTotal)

If obj.Execute("exec UpdateTotal @ID=?, @total=?") Then

' Success

Else

Dim strError as String = obj.GetLastError()

' more error handling code

End If

obj.Release()

End Sub

使用AddParameter()时,添加参数的顺序要和它们出现在sql文档中的一致。Execute()会运行一个sql命令来更新数据库。你也可以用GetXmlDocument()或GetXmlString()的参数来获取数据。在XMLDBComponent对象执行sql或查询命令后,添加的参数就被自动清除了。下次做同样的调用时,你需要再次添加参数。

简单事务

XMLDBComponent支持简单事务。现在就调用BeginTransaction()来开始一个新的事务。接下来做一些数据库工作。最后调用Commit()来完成事务。如果出现任何的数据库错误,事务会自动回滚,因此没有记住要回滚的必要。从开始事务之后,如果要改变已完成的工作,你随时都可以手工调用Rollback。

在你的应用中使用多个事务是没有任何问题(就像是用多个XMLDBComponent对象)的。但是,不允许使用嵌套。如果对一个对象两次调用BeginTransaction(),前一个事务在下一个开始前会回滚。

这里有一个比较复杂的例子。假设你有一个由多页面构成的.net的web应用。用户一个接一个的浏览页面,并把数据存到数据库中。在末页面中,所有从用户收集来的数据必须被确认或是重新更改。在首页中,你的程序会调用CreateObject() 然后是BeginTransaction()开始数据库工作。当用户移至下个页面,ID字串被传递,新的页面会调用CreateObject(),并以ID为参数获取在前一个页面中创建的对象。在最后一页,应用程序会调用Commit()来完成工作,并由Release()将对象返回池中。我从未在实际的应用中实践过这个方法,真正实现时可能会出现很多问题。

web服务

XMLDBService工程是一个用vb写的简单的web服务。它对所有的web潜在客户开发XMLDBComponent方法。这意味着,你的客户程序不用在它自己的地址空间中创建一个新的XMLDBComponent对象,而且不用把XMLDB.dll拷贝到客户程序运行的那个机器上。实际上,你都无需在客户机上安装.net框架和windows操作系统。(至少在理论上是这样的)。

除了一个额外的对象ID参数,web服务使用和XMLDBComponent类中几乎一样的方法。使用WEB服务的典型做法是首先调用CreateObject(),返回一个ID字符串,而非XMLDBComponent对象,来确认在远端WEB服务进程的对象池中未用的对象。

稍候,如果你需要调用

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有