NDO中的ActiveRecord 简介

          我开发的这个ActiveRecord 思想来源于现在非常火爆的Rails框架中的ActiveRecord - 活动记录,该模式来源于国际软件大师Martin Flowler所著的<<企业应用架构模式>>。文中Martin Flowler下了定义:一个对象,它包装数据库表或视图中的某一行,封装数据库访问,并在这些数据上增加了领域逻辑意思是说活动记录是一个实体对象,该实体对象代表数据库表或视图中的一行,并在该实体对象中封装了数据访问逻辑和业务逻辑代码,对象既有数据又有行为。该对象到底是数据对象?DAO对象?BIZ 对象呢? 马丁福莱道:领域模型,即BIZ对象(较业务对象)。ActiveRecord应用最广的是Ruby 中的Rails框架,并且把ActiveRecord的感念又大大延伸了.Rails框架中的ActiveRecord完全可以和JAVA中的hibernate 相比美,该框架中的"简单就是美","约定胜于配置"等敏捷思想深深的影响了我,使我产生开发NQL的一个动力.Rails中的活动记录支持一对多,多队一,多对多等对象关系映射模式.我做的ActiveRecord目前支持单表映射,对于一对多,多队一,多对多等映射模式以查询对象来代替.对于为什么要这样呢?"简单就是美",如果你把映射做的太多,太复杂,那学习成本就很高,于是我避开这一环节做了一个NQL强大的查询组件来做为ActiveRecord的助手,使ActiveRecord的概念仍停留在Martin Flowler的定义之中,没有达到完全的ORM目的。林学鹏开发的Grove rm 的思想和我的差不多,只做单表或视图的映射再配合上Oql语言,这在当时是非常火的,因为.NET 平台的一个优点就是短,平,快,果你做的太复杂反而用的就少,比如NHibernate,和Castle框架中的活动记录。至于将来是否支持一对多,多队一,多对多等映射模式,那时后话,有可能会支持的.。

ORM 性能比较(除了数据缓冲机制)

1. 映射比较

OR映射在hibernate和NHibernate中用xml做为映射的,映射的开销是输入输出操作以及DOM对象的解析

Grove的单表映射和Castle中的活动记录是用标签做映射,映射的开销是通过反射读取标签信息来得到映射信息

NDO 的ActiverRocord 或NQL通过直接读取数据库表的元数据做映射,映射开销是读数据库得到元数据。(注:这种方式说白了根本不叫映射,具体原因后面或做介绍)

通过读取元数据来看NDO 的ActiverRocord 或NQL的映射开销比较大。

2.对象的加载以及sql的动态生成

  当今流行的ORM框架,无论是以xml配置做映射还是标签做映射都需要通过反射来加载对象的数据,通过反射来动态生成sql.。

在这方面ActionPack 框架,Ruby on rails 或许我对rails理解有误)方面做的比较好,NDO 的ActiverRocord 就吸收了这两者的思

想,无论在数据的加载或sql的动态生成方面就没有任何反射开销,性能就相应的高了很多!

例子:下面的例子都是以Sql Server2000中的默认数据库Northwind为例

NDO中的活动记录支持三种类型,一种是弱类型,另外一种是强类型,第三种是强类型和弱类型之间,只有强类型的活动记录才能够完全支持从数据库中得到实体对象的IList集合,其它两种只支持返回DataTable,DataSet,DataReader等结果集对象

1。弱类型的例子:

   1.1数据加载Load ,或LoadByKey返回数据库中的一条记录,如果有多条只加载第一条记录

ActiveRecord product = new ActiveRecord("Products");
product.LoadByKey(
1);
this.Text = (string)product["ProductName"+ "--------" + product["SupplierID"];

SQL  输出

SELECT 
    
[ProductID],
    
[ProductName],
    
[SupplierID],
    
[CategoryID],
    
[QuantityPerUnit],
    
[UnitPrice],
    
[UnitsInStock],
    
[UnitsOnOrder],
    
[ReorderLevel],
    
[Discontinued]
FROM
    
[Products]    
WHERE
    
[ProductID]  = @ProductID

1.1数据加载 2

ActiveRecord product = new ActiveRecord("Products");
product.ID 
= 1;
product.Load();
this.Text = (string)product["ProductName"+ "--------" + product["SupplierID"];

SQL  输出同上

1.1 数据加载3 返回了多条记录但是只加载了一条

ActiveRecord product = new ActiveRecord("Products");
    product.SetValue(
"SupplierID",7);
product.Load();
 
this.Text = (string)product["ProductName"+ "--------" + product["SupplierID"];

SQL 输出

SELECT 
    
[ProductID],
    
[ProductName],
    
[SupplierID],
    
[CategoryID],
    
[QuantityPerUnit],
    
[UnitPrice],
    
[UnitsInStock],
    
[UnitsOnOrder],
    
[ReorderLevel],
    
[Discontinued]
FROM
    
[Products]
WHERE
    
[SupplierID]=@SupplierID

1.2 数据查询(返回零条或多条记录,这个类似与Quey对象的用法,活动记录里面封装了CRUD的四个查询对象方便用户更灵活的操作数据库)

ActiveRecord product = new ActiveRecord("Products");
this.dataGrid1.DataSource = product
                .SelectCommand
                .NewWhere(
"SupplierID",7)
                .And(
"CategoryID",3)
                .GetDataTable();

SQL 输出

SELECT 
    
[ProductID],
    
[ProductName],
    
[SupplierID],
    
[CategoryID],
    
[QuantityPerUnit],
    
[UnitPrice],
    
[UnitsInStock],
    
[UnitsOnOrder],
    
[ReorderLevel],
    
[Discontinued]
FROM
    
[Products]    
WHERE
    
[SupplierID]  = @SupplierID
    
AND [CategoryID]  = @CategoryID

1.3 数据插入操作

ActiveRecord rg = new ActiveRecord("Region");
rg.ID 
= 6;
rg[
"RegionDescription"= "66";           
    rg.Save();

SQL  输出

INSERT INTO [Region] (
    
[RegionID],
    
[RegionDescription]
VALUES (
    @RegionID,
    @RegionDescription
)

1.4数据更新

ActiveRecord rg = new ActiveRecord("Region");
rg.ID 
= 6;
    rg.Load();
rg[
"RegionDescription"= "66666";           
    rg.Save();

SQL 输出

SELECT 
    
[RegionID],
    
[RegionDescription]
FROM
    
[Region]
WHERE
    
[RegionID]=@RegionID

UPDATE [Region] SET 
    
[RegionDescription] = @RegionDescription
WHERE
    RegionID 
= @RegionID

1.5 数据删除

ActiveRecord rg = new ActiveRecord("Region");
rg.ID
=6;
rg.Delete();

SQL  输出

DELETE FROM [Region]
WHERE
    RegionID 
= @RegionID

1.5 数据删除2(条件删除(活动记录里面封装了Table数据库表的元数据对象里面),也可以以Filter方式进行删除或Where子句的方式进行删除)

ActiveRecord rg = new ActiveRecord("Region");          
   Condition con = rg.DeleteCommand.NewCondition(rg.Table.Key.Columns[0].Name) == 6;
con.Execute();

SQL  输出同上

上一篇   下一篇

posted @ 2006-10-30 18:48  风云  阅读(2922)  评论(12编辑  收藏  举报