首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

通过“访问多种数据库”的代码来学习多态!(.net2.0版) (外加散分),该怎么处理

2012-01-01 
通过“访问多种数据库”的代码来学习多态!(.net2.0版) (外加散分)http://www.cnblogs.com/jyk/archive/2007/

通过“访问多种数据库”的代码来学习多态!(.net2.0版) (外加散分)
http://www.cnblogs.com/jyk/archive/2007/04/23/723519.html


本帖子针对初学者,如果您是老鸟可以略过。

语言环境:   asp.net2.0   。数据库没什么了,反正是要到达访问多种数据库的目的,但是语言一定是.net2.0。因为有几个地方.net1.1是不支持的。

目的:使用ADO.net访问多种数据库。

对于一个网站来说,访问数据库可以说是一个很基本的功能了,那么怎么实现这个功能呢?

假设我们要从数据库里读取News表里面的记录,那么常见的代码也许是这样的。

 

sql的访问方法
  1public   class   DALSQL
  2         {
  3                 public   DataTable   GetNewsList()
  4                 {
  5                         SqlConnection   cn   =   new   SqlConnection(DALFactory.cnString);//DALFactory.cnString   是什么?就是获取连接字符串,下面有说明
  6                         SqlDataAdapter   da   =   new   SqlDataAdapter( "select   *   from   News ",   cn);
  7                         DataTable   dt   =   new   DataTable();
  8
  9                         da.Fill(dt);//这里我不喜欢加名字,我觉得没有必要。
10
11                         return   dt;
12                 }
13         }
 

这样写没有什么错误,但是如果想要更换数据库怎么办呢?比如现在是SQL   2000,但是由于某种原因要换成Access,那么要怎么写代码呢?

 

OleDb的访问方法
  1public   class   DALOleDb
  2         {
  3                 public   DataTable   GetNewsList()
  4                 {
  5                         OleDbConnection   cn   =   new   OleDbConnection(DALFactory.cnString);
  6                         OleDbDataAdapter   da   =   new   OleDbDataAdapter( "select   *   from   News ",   cn);
  7                         DataTable   dt   =   new   DataTable();
  8
  9                         da.Fill(dt);//这里我不喜欢加名字,我觉得没有必要。
10
11                         return   dt;
12                 }
13         }


其实要改的地方并不多,只是把“Sql”换成“OleDb”就可以了。但是表多了就麻烦了,每一个地方都要改一遍,既繁琐又容易出错,怎么办?这时候就可以使用“多态”来解决更换数据库的问题。

先要补充两个基础知识,一个就是继承和多态。继承都不能理解的话,多态就不要想了。我见过的最简单易懂的是博客圆里的小菜编程成长记系列,那里讲得很明白了,我就不多说了(没有他说的那么好)。

http://www.cnblogs.com/cj723/archive/2007/04/02/697431.html     小菜编程成长记系列   (我就是通过这个系列才学会的。这里做一个简单的应用)

另一个基础知识就是,ADO.net的内部结构。当然不是要全部了解,只需要先了解一点点。我们可以借助Reflector.exe来查看内部代码。(Reflector的使用方法请到搜索引擎里找一下)


在.net2.0(.net1.1不是这样的,请注意)里面我们可以发现   SqlConnection、OleDbConnection等都是继承自DbConnection。他是一个抽象基类(如果不清楚的话可以先当作父类来看),就是说DbConnection   派生出了   SqlConnection   、OleDbConnection等,这些合起来就“构成”了多态。(用“构成”可能不太准确)。


掌握了以上两点后,我们的代码就好写了。

先写一个函数,返回实例



 

用工厂返回实例
  1public   class   DALFactory
  2         {
  3                 public   static   string   cnString   =   System.Web.Configuration.WebConfigurationManager.AppSettings[ "ConnString "];
  4            
  5                 public   static   DbConnection   CreateConnection()
  6                 {
  7                         string   DataType   =   "1 ";
  8                         DbConnection   cn   =   null;
  9
10                         switch   (DataType)
11                         {
12                                 case   "1 ":
13                                         cn   =   new   SqlConnection(cnString);
14                                         break;
15                                 case   "3 ":
16                                         cn   =   new   OleDbConnection(cnString);
17                                         break;
18                         }
19
20                         return   cn;
21                 }
22
23                 public   static   DbDataAdapter   CreateDataAdapter(string   sql,DbConnection   cn)
24                 {
25                         string   DataType   =   "1 ";
26                         DbDataAdapter   da   =   null;
27
28                         switch   (DataType)
29                         {
30                                 case   "1 ":
31                                         da   =   new   SqlDataAdapter(sql,   (SqlConnection)cn);
32                                         break;


33                                 case   "3 ":
34                                         da   =   new   OleDbDataAdapter(sql,   (OleDbConnection)cn);
35                                         break;
36                         }
37
38                         return   da;
39                 }
40         }
 

这个函数是不是传说中的简单工厂模式呢?
(if   (true){看,我们并不知道什么模式,但是我们从实际需求中很自然的就应用了一个模式}else{算我学艺不精})

把开始的两个函数合并。

 

访问多种数据库的一个方法
  1public   class   DAL
  2         {
  3                 public   static   DataTable   GetNewsList()
  4                 {
  5                         DbConnection   cn   =   DALFactory.CreateConnection();
  6                         DbDataAdapter   da   =   DALFactory.CreateDataAdapter( "select   *   from   News   ",cn);
  7                         DataTable   dt   =   new   DataTable();
  8
  9                         da.Fill(dt);
10
11                         return   dt;
12                 }
13         }
 

这样呢换数据库了,我们只要改一下,等等,用改函数吗?不需要的,我们只需要把数据库类型放到web.config里面,在   里面读取就可以了,换数据库也不用改代码了。(理想情况下是这样的,但是实际中往往是很复杂的,这里就先不讨论了)。


当然   还是可以再提炼一下的。这里只是为了演示多态,写的不够严谨,实际应用中还要好好考虑设计一下。

让我们来回顾一下使用多态的情况:

从程序的角度来讲:

1、首先要写一个基类,然后写若干子类继承这个基类。
            DbConntion是.net2.0里面自带的,不用我们去写了。SqlConntion就是一个子类,用于SQL数据库的连接。
            只是.ne1.1里面并没有这么设计,所以我才说我的这个方法目前只适合.net2.0。

2、写一个简单工厂根据条件来返回需要的子类。

3、定义一个基类,然后调用工厂获取实例。

从需求的角度来讲:

多种情况都有相同的叫法(比如打开数据库),但是每一种情况的实现方式又都不一样。

ps:
1、为了能够突出重点(多态),所以访问数据库的地方没有使用try,也没有使用using()。一是想简化代码;一是避免争论,使用try还是using本身就有争论,而这里不想讨论这个。所以就没有加。

2、连接字符串的处理也比较“睡意”,并不是很严密。这个有空的话会详细说明的。

3、CreateDataAdapter   函数的处理方法也不是太好,并不是太理想。这里侧重的是多态的应用,并不是具体代码的实现。有空我会写一下我的访问数据库的方法。

4、DataType   应该从Web.config里面读取信息,这里省略了。

5、以上代码已经在vs2005   +   sql2005的环境下测试成功。



[解决办法]
public sealed class DataAccess {

// Look up the DAL implementation we should be using
private static readonly string path = ConfigurationManager.AppSettings[ "WebDAL "];
private static readonly string orderPath = ConfigurationManager.AppSettings[ "OrdersDAL "];

private DataAccess() { }


public static PetShop.IDAL.ICategory CreateCategory() {
string className = path + ".Category ";
return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IInventory CreateInventory() {
string className = path + ".Inventory ";
return (PetShop.IDAL.IInventory)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IItem CreateItem() {
string className = path + ".Item ";
return (PetShop.IDAL.IItem)Assembly.Load(path).CreateInstance(className);
}

public static PetShop.IDAL.IOrder CreateOrder() {
string className = orderPath + ".Order ";
return (PetShop.IDAL.IOrder)Assembly.Load(orderPath).CreateInstance(className);
}

public static PetShop.IDAL.IProduct CreateProduct() {
string className = path + ".Product ";
return (PetShop.IDAL.IProduct)Assembly.Load(path).CreateInstance(className);
}


道理一样 只是写的更迷惑人了
[解决办法]
学习 不过一直不明白什么是工厂模式
---------工厂模式:
意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
适用性
􀁺 当一个类不知道它所必须创建的对象的类的时候。
􀁺 当一个类希望由它的子类来指定它所创建的对象的时候。
􀁺 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

不是很理解 楼主能讲解一下么

热点排行