科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道.net环境中数据库访问组件的应用

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:中国IT实验室 来源:中国IT实验室 2007年9月29日

关键字: 编程

  • 评论
  • 分享微博
  • 分享邮件
  
  最近我写了一个.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服务进程的对象池中未用的对象。
  
  稍候,如果你需要调用

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章