OraclePetShop数据访问层的数据库访问计划

《解剖PetShop》系列的二

老二、PetShop数据访问层的数据库访问计划
当系列一中,我起整体达标析了PetShop的架构设计,并提及了子的概念。从本有的开始,我将顺序对各级层进行代码级的辨析,以要获得进一步缜密而深入之知道。在PetShop
4.0被,由于引入了ASP.Net
2.0底片初特点,所以数据层的情吗愈加的广大与复杂性,包括:数据库访问、Messaging、MemberShip、Profile四部分。在浩如烟海二丁,我将介绍有关数据库访问的筹划。

每当PetShop中,系统要处理的数据库对象分为两好像:一凡是数量实体,对诺数据库中相应的数据表。它们并未表现,仅用于表现对象的数目。这些实体类都于放到Model程序集中,例如数据表Order对应之实业类OrderInfo,其类图如下: 

Oracle 1

这些目标并无享持久化的机能,简单地说,它们是作为数据的载体,便于工作逻辑针对相应数据表进行读/写操作。虽然这些近似的性质分别映射了数据表的排,而诸一个靶实例也恰恰对应于数据表的各国一样实施,但这些实体类可连无享相应之数据库访问能力。

是因为数量看层及工作逻辑层都拿本着这些数据实体进行操作,因此次集Model会于随即简单交汇的模块所引述。

仲类数据库对象则是数额的事体逻辑对象。这里所依赖的政工逻辑,并非业务逻辑层意义及之天地(domain)业务逻辑(从这意思及,我还倾向被用业务逻辑层称为“领域逻辑层”),一般意义上说,这些业务逻辑就是为主导的数据库操作,包括Select,Insert,Update和Delete。由于这些业务逻辑对象,仅具有行一旦和数量无关,因此她均为架空为一个独立的接口模块IDAL,例如数据表Order对应的接口IOrder: 

Oracle 2

以数据实体和有关的数据库操作分离出来,符合面向对象的神气。首先,它体现了“职责分开”的规则。将数据实体和那个行为分开,使得两者之间依赖减弱,当数作为发出变动时,并无影响Model模块中的数码实体对象,避免了因为一个类职责过多、过特别,从而造成该类的引用者发生“灾难性”的熏陶。其次,它体现了“抽象”的动感,或者说是“面向接口编程”的特等体现。抽象的接口模块IDAL,与现实的数据库访问实现全隔离。这种与落实无关之计划性,保证了系统的只是扩展性,同时为管了数据库的可移植性。在PetShop中,可以支持SQL
Server和Oracle,那么她具体的兑现即分别放在两个不等之模块SQLServerDAL、OracleDAL中。

坐Order为条例,在SQLServerDAL、OracleDAL两个模块中,有例外的兑现,但她又还要还实现了IOrder接口,如图: 

Oracle 3

由数据库的兑现来拘禁,PetShop体现出了没ORM框架的重叠和丑陋。由于要针对数据表进行Insert和Select操作,以SQL
Server为条例,就利用了SqlCommand,SqlParameter,SqlDataReader等目标,以得这些操作。尤其复杂的是Parameter的传递,在PetShop中,使用了大气底字符串常量来保存参数的称。此外,PetShop还特地为SQL
Server和Oracle提供了纸上谈兵的Helper类,包装了有些常用之操作,如ExecuteNonQuery、ExecuteReader等方法。

在没ORM的情形下,使用Helper类是一个比较好的国策,利用其来形成数据库基本操作的包,可以减掉过多以及数据库操作有关的代码,这体现了对象复用的条件。PetShop将这些Helper类统一置于DBUtility模块中,不同数据库的Helper类暴露的章程基本相同,只除了有的奇特的求,例如Oracle中处理bool类型的道就是与SQL
Server不同,从而专门提供了OraBit和OraBool方法。此外,Helper类中的艺术均为static方法,以有利于调用。OracleHelper的类图如下: 

Oracle 4

对数据访问层来说,最头疼的凡SQL语句之处理。在前期的CS结构中,由于匪运三层式架构设计,数据访问层以及业务逻辑层是紧密糅合在一起的,因此,SQL语句遍布与网的各个一个角落。这叫程序的掩护带来极大的孤苦。此外,由于Oracle使用的凡PL-SQL,而SQL
Server和Sybase等利用的凡T-SQL,两者虽然还按了正规SQL的语法,但以重重细节及仍发生分别,如果以SQL语句大量底动及程序中,无疑也可能的数据库移植也拉动了困难。

尽好的方是使用储存过程。这种艺术教程序更加清新,此外,由于存储过程得因数据库脚本的形式在,也便于移植和改动。但这种方式还是有弱点。一凡是储存过程的测试相对艰苦。虽然有对应的调试工具,但于从针对代码的调节而言,仍然比较复杂且非便宜。二凡是针对系统的换代带来阻力。如果数据库访问是出于程序完成,在.Net平台下,我们一味用以窜程序后,将还编译的次第集xcopy到布置之服务器上即可。如果用了储存过程,出于安全的设想,必须来专门的DBA重新运行存储过程的本子,部署之主意受了限。

自己都于一个档次遭到,利用一个特意的表来存放SQL语句。如要使相关的SQL语句,就动重大字搜索得到对承诺谈。这种做法近似于储存过程的调用,但可避免了配备及的题材。然而这种方式可于性能上无法取保证。它独自可为SQL语句较少之面貌。不过,利用好的宏图,我们可以吗各种事务提供不同之表来存放SQL语句。同样的道理,这些SQL语句也足以存放到XML文件中,更利于系统的恢弘或修改。不过前提是,我们用为其提供专门的SQL语句管理工具。

SQL语句之运用无法避免,如何更好的行使SQL语句也无定论,但生一个准值得咱们遵守,就是“应该尽量让SQL语句尽存在于数量访问层的求实实现中”。

当,如果下ORM,那么万事就变得不同了。因为ORM框架已也数看提供了核心的Select,Insert,Update和Delete操作了。例如在NHibernate中,我们得一直调用ISession对象的Save方法,来Insert(或者说是Create)一个多少实体对象:
public void Insert(OrderInfo order)
{
    ISession s = Sessions.GetSession();
    ITransaction trans = null;
    try
    {
    trans = s.BeginTransaction();
      s.Save( order);
      trans.Commit();
    }
    finally
    {
      s.Close();
    }
}

从未SQL语句,也并未那些烦人的Parameters,甚至不欲专门去考虑工作。此外,这样的计划性,也是暨数据库无关之,NHibernate可以通过Dialect(方言)的机制支持不同的数据库。唯一要召开的是,我们用为OrderInfo定义hbm文件。

本,ORM框架并非是全能的,面对纷繁复杂的作业逻辑,它并无能够完全扑灭SQL语句,以及代表复杂的数据库访问逻辑,但它却格外好之反映了“80/20(或90/10)法虽”(也为称之为“帕累托法则”),也不怕是说:花比较少(10%-20%)的力气就可以化解大部分(80%-90%)的题材,而如果解决剩下的少部分题目虽用差不多得几近之竭力。至少,那些当数看层中占了多方底CRUD操作,通过下ORM框架,我们即便只需要交极个别光阴与精力来解决它们了。这的确缩短了全项目开之周期。

或者回对PetShop的讨论上来。现在我们都起了数额实体,数据对象的肤浅接口和兑现,可以说关于数据库访问的本位就曾经做到了。留待我们的还有个别单问题用缓解:
1、数据对象创建的治本
2、利于数据库的移植

每当PetShop中,要创造的数目对象包括Order,Product,Category,Inventory,Item。在前方的筹划被,这些目标就给架空为对应之接口,而那个实现则根据数据库的差而有所不同。也就是说,创建的对象来多类,而各个种类型又生出两样之兑现,这是突出的纸上谈兵工厂模式之动场景。而者所陈述之鲜只问题,也还好经过架空工厂模式来解决。标准的肤浅工厂模式类图如下: 

Oracle 5

比如说,创建SQL Server的Order对象如下:
PetShopFactory factory = new SQLServerFactory();
IOrder = factory.CreateOrder();

如若考虑到数据库的可移植性,则factory必须作一个全局变量,并当预告程序运行时受实例化。但诸如此类的计划虽已经达到了“封装变化”的目的,但当创造PetShopFactory对象时,仍不可避免的出现了实际的类SQLServerFactory,也便凡是说,程序于此规模上出了和SQLServerFactory的强依赖。一旦通体系要求支持Oracle,那么还欲改就行代码为:
PetShopFactory factory = new OracleFactory();

修改代码的这种行为显然是不行接受的。解决之法是“依赖注入”。“依赖注入”的法力通常是用特别的IoC容器提供的,在Java平台下,这样的容器包括Spring,PicoContainer等。而当.Net平台下,最广大的虽然是Spring.Net。不过,在PetShop系统中,并不需要专门的器皿来促成“依赖注入”,简单的做法还是使用配置文件与反光功能来落实。也就是说,我们可以web.config文件中,配置好实际的Factory对象的圆的类名。然而,当我们下配置文件以及反光作用时,具体工厂的创造就显示有点“画蛇添足”了,我们一齐可以安排文件被,直接针对具体的数据库对象实现类似,例如PetShop.SQLServerDAL.IOrder。那么,抽象工厂模式被的连锁工厂便好简化为一个工厂类了,所以我将这种模式称之为“具有简易工厂特质的悬空工厂模式”,其类图如下: 

Oracle 6

DataAccess类完全代表了前头创建的工厂类系,它是一个sealed类,其中创建各种数据对象的章程,均为静态方法。之所以能就此这看似及抽象工厂的目的,是盖安排文件及反光的使用,如下的代码片断所示:
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”];

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

在PetShop中,这种靠配置文件和反光创建对象的办法最好普遍,包括IBLLStategy、CacheDependencyFactory等等。这些实现逻辑散布于所有PetShop系统被,在我看来,是足以于这基础及开展重构的。也就是说,我们好啊整系统提供类似于“Service
Locator”的兑现:
public static class ServiceLocator
{
 private static readonly string dalPath =
ConfigurationManager.AppSettings[“WebDAL”];
    private static readonly string orderPath =
ConfigurationManager.AppSettings[“OrdersDAL”];
 //……
 private static readonly string orderStategyPath =
ConfigurationManager.AppSettings[“OrderStrategyAssembly”];

 public static object LocateDALObject(string className)
 {
  string fullPath = dalPath + “.” + className;
  return Assembly.Load(dalPath).CreateInstance(fullPath);
 }
public static object LocateDALOrderObject(string className)
 {
  string fullPath = orderPath + “.” + className;
  return Assembly.Load(orderPath).CreateInstance(fullPath);
 }
public static object LocateOrderStrategyObject(string className)
 {
  string fullPath = orderStategyPath + “.” + className;
  return Assembly.Load(orderStategyPath).CreateInstance(fullPath);
 }
 //……
}

那么和所谓“依赖注入”相关的代码都可行使ServiceLocator来完成。例如类DataAccess就足以简化为:
public sealed class DataAccess
{
 public static PetShop.IDAL.IOrder CreateOrder()
 {
         return (PetShop.IDAL.IOrder)ServiceLocator.
LocateDALOrderObject(“Order”);
    }
}

透过ServiceLocator,将有着和配置文件有关的namespace值统一管理起,这好各种动态创建对象的军事管制暨前景之保护。

相关文章