知识大全 漫谈.Net PetShop和Duwamish ADO.NET数据库编程
Posted 数据库
篇首语:少年辛苦终身事,莫向光阴惰寸功。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 漫谈.Net PetShop和Duwamish ADO.NET数据库编程相关的知识,希望对你有一定的参考价值。
漫谈.Net PetShop和Duwamish ADO.NET数据库编程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
概述 ADO NET为我们提供了强大的数据库开发能力 它内置的多个对象为我们的数据库编程提供了不同的选择 但是在允许我们灵活选用的同时 许多初学者也很迷惑 我到底是应该使用DataReader还是应该使用DataAdapter?我只想读取一小部分数据 难道我一定要Fill满整个DataSet吗?为什么DataReader不能和RecordSet一样提供一个数据更新的方法?DataSet到底有什么好处? 在本文中 我将 PetShop的数据库编程模式和Duwamish的数据库编程模式进行一些简单的分析和对比 如果您也有以上疑问的话 相信在读完本文之后 就可以根据具体的需要来制定一个最适合您应用的数据库编程模式 Net PetShop和Duwamish简单介绍 相信大家一定听说过有名的 宠物店大战 没错 本文的主角之一就是获胜方 Net PetShop 微软号称以 倍的速度和 / 的代码量遥遥领先于基于J EE的PetStore宠物商店 虽然SUN也曾对此抱怨过不满 指责此 大战 有水分 不过无论如何 Net PetShop绝对是一个经典的 Net实例教程 至少为我们提供了一条赶超J EE的 捷径= ) 它的下载地址是
Net PetShop宠物网上商店首页
而Duwamish则是一个外表简单 内部却极其复杂的一个网上书店的 Net完整应用范例 作为一个微软官方的Sample 它同时提供了C#和VB Net两种语言版本 并且还附上了大量详尽的中文资料 如果打印出来 实在是居家旅行 临睡入厕必备之物 什么?您没听说过?呵呵 如果您装了Visual Studio Net的话 它就在您的硬盘上静静的躺着呢 不过还没有被安装 您可以在您的 的EntERPrise Samples目录下找到并安装它 例如 C:\\Program Files\\Microsoft Visual Studio NET\\Enterprise Samples\\Duwamish CS
Duwamish网上电子书店首页
结构简述 两家商店都采用了n层应用结构(毫无疑问 n层结构的应用架构应该绝对是您开发 Net应用的首选 哪怕您只想做一个网页计数器) 不同的是 PetShop采用的是最常见的三层应用结构 分别为表示层 中间层和数据层 而Duwamish则采用的是一个四层应用结构 并使用不同的项目分隔开 分别为表示层 业务外观层 业务规则层和数据层 至于这两种结构分别有什么优点和缺点 以及为什么要这么分层 我们不进行详细讨论 因为本文的重点不在于此 我们主要分析的是他们的数据库编程的模式 Duwamish数据访问剖析
首先 我们来看看Duwamish书店 它采用的是DataAdapter和DataSet配合的数据存储模式 所不同的是 它对DataSet进行子类化扩展作为数据载体 也就是采用定制的DataSet来进行层间的数据传输 下面是一个定制的DataSet示例
public class BookData : DataSet public BookData() // // Create the tables in the dataset // BuildDataTables(); private void BuildDataTables() // // Create the Books table // DataTable table = new DataTable(BOOKS_TABLE); DataColumnCollection columns = table Columns;
columns Add(PKID_FIELD typeof(System Int )); columns Add(TYPE_ID_FIELD typeof(System Int )); columns Add(PUBLISHER_ID_FIELD typeof(System Int )); columns Add(PUBLICATION_YEAR_FIELD typeof(System Int )); columns Add(ISBN_FIELD typeof(System String)); columns Add(IMAGE_FILE_SPEC_FIELD typeof(System String)); columns Add(TITLE_FIELD typeof(System String)); columns Add(DESCRIPTION_FIELD typeof(System String)); columns Add(UNIT_PRICE_FIELD typeof(System Decimal)); columns Add(UNIT_COST_FIELD typeof(System Decimal)); columns Add(ITEM_TYPE_FIELD typeof(System String)); columns Add(PUBLISHER_NAME_FIELD typeof(System String));
this Tables Add(table); ………
我们可以看到它有一个BuildDataTables方法 并且在构造函数中调用 这样 定制的Books表就和这个DataSet捆绑在一起了 省得以后还要进行Column Mapping 这真是个好主意 我怎么就没有想到呢? )
解决了数据结构 接下来看看数据层的代码实现 在Duwamish中 数据层中有 个类 分别是Books Categories Customers和Orders 每个类分别只负责有关数据的存取 下面是其中一个类的示例代码
private SqlDataAdapter dsCommand;public BookData GetBookById(int bookId) return FillBookData( GetBookById @BookId bookId ToString());private BookData FillBookData(String mandText String paramName String paramValue) if (dsCommand == null ) throw new System ObjectDisposedException( GetType() FullName ); BookData data = new BookData(); SqlCommand mand = dsCommand SelectCommand;
mand CommandText = mandText; mand CommandType = CommandType StoredProcedure; // use stored proc for perf SqlParameter param = new SqlParameter(paramName SqlDbType NVarChar ); param Value = paramValue; mand Parameters Add(param);
dsCommand Fill(data); return data;
这里就是数据层的代码了 我们在这里可以看到Duwamish采用了DataAdapter来将数据填充到定制的DataSet中 然后返回该DataSet 我感到很奇怪的是在数据存取层中竟然可以看到GetBookById这样具体的数据存取方法 虽然最后还是有一个抽象出来的FillBookData方法 但是上面还有三层啊 底层都做到这份上了 那上层都做些什么呢?答案是数据检查 上层基本上都在做一些很严密的数据合法性校验(当然也会包括一些比较复杂的事务逻辑 但是并不多) 示例代码如下
public CustomerData GetCustomerByEmail(String emailAddress String password) // // Check preconditions // ApplicationAssert CheckCondition(emailAddress != String Empty Email address is required ApplicationAssert LineNumber); ApplicationAssert CheckCondition(password != String Empty Password is required ApplicationAssert LineNumber); // // Get the customer dataSet // CustomerData dataSet; using (DataAccess Customers customersDataAccess = new DataAccess Customers()) dataSet = customersDataAccess LoadCustomerByEmail(emailAddress); // // Verify the customer s password // DataRowCollection rows = dataSet Tables[CustomerData CUSTOMERS_TABLE] Rows;
if ( ( rows Count == ) && rows[ ][CustomerData PASSWORD_FIELD] Equals(password) ) return dataSet; else return null;
在这个方法中 真正进行数据存取的实际上只有
dataSet = customersDataAccess LoadCustomerByEmail(emailAddress);
这么一句 是直接调用的数据层 其它都是在进行合法性校验 我们可以感悟到 进行一个真正的企业级开发需要考虑的系统健壮性有多么重要
PetShop数据访问剖析
OK Duwamish看完了 下面我们来看看PetShop的数据访问机制
PetShop只有一个项目 它采用的分层办法是将中间层和数据层都写成cs文件放在Components目录里 其中数据层就是一个名为Database的类 它封装了所有对数据库的底层操作 下面是示例代码段
public void RunProc(string procName out SqlDataReader dataReader) SqlCommand cmd = CreateCommand(procName null);dataReader = cmd ExecuteReader(System Data CommandBehavior CloseConnection);
我们看到了一个跟Duwamish截然不同的另一种数据访问方式 它将所有的数据访问方法抽象出来做成一个RunProc方法 至于返回数据呢 呵呵 它有点偷懒 直接返回一个DataReader给你 你自己去读吧 还记得Duwamish采用的层间数据传输载体是什么吗?对了 是DataSet 它被数据层填充后返回给了中间层 但是这里 数据层和传输层的数据传输载体变成了DataReader 实际上 还不能称它为数据载体 因为数据还没开始读呢 在这里 DataReader的作用和指针有点类似 也许我们应该称它为 数据引用 )
接着往下看 DataReader被怎么 处理 的
public ProductResults[] GetList(string catid int currentPage int pageSize ref int numResults)numResults = ;int index= ;SqlDataReader reader = GetList(catid);ProductResults[] results = new ProductResults[pageSize];
// now loop through the list and pull out items of the specified pageint start = (int)((currentPage ) * pageSize);if (start <= ) start = ;
// skipfor (int i = ; i < start ; i++) if (reader Read()) numResults++;if (start > ) reader Read();
// read the data we are interested inwhile (reader Read()) if (index < pageSize) results[index] = new ProductResults();results[index] productid = reader GetString( );results[index] name = reader GetString( );index++;numResults++;
reader Close();
// see if need to redim arrayif (index == pageSize)return results;else // not a full page redim arrayProductResults[] results = new ProductResults[index];Array Copy(results results index);return results ;
注意到currentPage和pageSize了吗?原来在这里就进行了数据分页 只返回满足需要的最少的数据量 而不是象我们很多喜欢偷懒的人一样 简单的将整个DataTable一股脑的绑定到DataGrid 造成大量的数据冗余
在这里 数据被真正的读出来 并且被手动填充到一个自定义的对象数组中 我们来看看这个数组的定义
public class ProductResultsprivate string m_productid;private string m_name;
// product propspublic string productid get return m_productid; set m_productid = value;
public string name get return m_name; set m_name = value;
非常之简单 不过我有点奇怪为什么不使用struct呢?是不是 Net中struct和class的性能差距已经可以忽略不计了?
分析总结
通过观察这两个商店的具体实现 我们得到了两个不同的数据访问模式 Duwamish采用的是以DataSet为核心 因为DataSet提供了这方面大量的相关方法 所以整个应用的数据传输 数据格式定义 数据校验都围绕着DataSet来进行 整个架构定义非常清晰和严谨 但是却显得有些庞大 PetShop在整个程序中没有采用一个DataSet 程序非常的简洁 轻灵 但是没有Duwamish那么强的健壮性 这两个程序是Microsoft公司不同的小组写出来的代码 所以有着不同风格 不过都应该能代表 Net的标准模式 看到这里 你应该对文章开头提出的那些疑问有一个比较形象的认识了吧
另外 请再次注意 PetShop在打开数据连接之后 并没有马上读取数据 而是将DataReader传递给另外的对象来执行数据读的操作 然后才关闭连接 这样 数据连接的时间加长了 而数据库连接是一项非常宝贵的服务器资源 相比之下 Dawamish在连接数据库之后马上进行填充 然后迅速释放掉数据库连接的方式更加有利于大量用户的并发访问
再一点 上文的程序中没有提到更新操作 PetShop采用的是使用Command对象执行单个存储过程的方式来进行更新操作 是属于一种在线即时数据更新模式 而Dawamish采用的是DataAdapter的Update方法 将DataSet的改变一次性的提交到数据库中 属于离线数据更新模式 这种模式的好处是可以一次性更新大批量数据 减少数据库的连接次数 缺点是如果数据库在改动非常频繁的情况下需要实时的跟踪数据变化就不合适了 需要根据具体的情况采用具体的数据更新办法
总的来说 如果您只需要快速的读取数据并显示出来 推荐您采用DataReader 如果您需要对数据进行大量的修改 还有大量并发访问的可能 而且不需要实时的跟踪数据库的变化 推荐您使用DataSet 当然 这两种情况有点极端了 实际的应用环境也许有着很复杂的条件 具体需要您自己审时度势 综合采用 不过我个人还是比较喜欢PetShop那种轻灵的风格 )
cha138/Article/program/net/201311/13509相关参考
漫谈.Net开发关于命名空间和目录划分 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &
.NetPetShop4.0分布式数据库设计 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!数据库作
PetShop——数据类库Model 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n
PetShop——经典的数据库连接 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nb
petshop充分体现了面向接口编程的思想就是给你一个接口你别管我是怎么实现的你只管用别说其他的 na
中医讲究按照一年四季气候阴阳变化的规律和特点,从饮食、生活习惯等方面进行调养、健身和防病,从而达到养生和益寿延年的目的,在此介绍关于秋季饮食养生的一点小知识。秋季是从立秋至立冬三个月。秋季的特点是由热
《礼记·月令篇》提到:“季秋之月,鞠有黄华”,古人提到的黄华是一种野菊花,在秋季最后一个月的季秋盛放。在那个年代,菊花都是野生种,花是黄色的。后来,古人发现,这种小小的黄色的野菊花是可以食用和药用
真正的虾类都有五对步足。在游泳亚目中,共有三类,即对虾类、真虾类和经济意义不大的?虾类。在众多的虾当中,体型大而资源丰富的食用种并不太多。就是在1590种真虾类中,
唐代散文大师韩愈说过:“与其有乐于身,孰若无忧于其心”。内心的快乐,才是千金难买。凡是希望长寿者,平时就应加强自身道德素质修养和心理素质修养,锻炼自己的性格,养成情绪稳定,遇事不动肝火,不生闷气,精神
云,天上飘荡的云朵;雨,落到地上的雨水。这是幼儿园的小朋友都知道的自然现象。但在古人看来,男人和女人之间也有“云雨”之事。这里的“云雨”,就是性交的意思。云彩雨水被理解为成年男女间的交合造爱,这说明了