DataRabbit的背后(1)-―走进DataRabbit上下文
一个概念只有将其放到一个具体的上下文中,其含义和作用才会清晰、明确。脱离了上下文,概念就失去了其价值和生命力。所以,学习使用任何技术或概念的时候,有一件事情是非常重要的,那就是透彻地理解该技术概念所位于的上下文,这将有助于我们更好地使用和驾驭这个技术。
在ORM流行的今天,数据访问框架层出不穷,但是这些框架所基于的上下文几乎都会有些不一样,要想将一个数据访问框架运用得炉火纯青,必须要掌握该框架所基于的上下文。同理,如果你想发挥DataRabbit框架的巨大威力,在之前,你绝对有必要了解一下DataRbbit的上下文。
一.纯ORM ?
在DataRabbit发展过程中,我曾作了一个非常重要的决定:不能把DataRabbit定位为一个纯粹的ORM框架,即所有的数据访问功能都基于ORM来实现。原因很简单,ORM并不能完成所有的事情(即使能完成所有的事情,那么也需要花费巨大的代价),有些数据库访问还是需要基于关系来进行,对于那些不提供基于关系进行数据访问操作的纯ORM框架,我认为其决策是不明智的。所以,在DataRabbit中,基于ORM的数据访问和基于关系的数据访问各占了一半的天空,这使得我们在无法用ORM达成或很难使用ORM达成的地方,可以转向使用基于关系的访问器来达成。
除了核心的ORM访问器和基于关系的访问器来访问数据表中的数据外,DataRabbit还提供对数据表的“大纲”进行访问和操作的功能,这是因为我们经常有这样的需求:获取数据表的某个字段的信息、或找到主外键关系、或者需要动态创建一个具有指定大纲的数据表。目前版本的DataRabbit提供的大纲操作功能还比较单薄,以后会逐渐进行增强。
二.DataRabbit中的核心理念
1.轻量、弱侵入性。比如,DataRabbit对你的数据库设计没有任何要求(而有的数据访问框架可能要求数据表必须有唯一主键)。
2.约定优于配置。使用DataRabbit不需要任何配置,这使得DataRabbit更加易用。
3.数据库类型无关性。统一的数据访问接口屏蔽了数据库类型的差异,目前版本的DataRabbit内置了对SqlServer和Oracle的支持,可以通过插件的方式来支持其它类型的数据库。
4.DataRabbit中的所有数据访问功能都是由各种访问器(如IOrmAccesser、IRelationAccesser、ITableAccesser、IDataSchemaAccesser、IEntityRelationLoader、ISPAccesser)来提供的。
5.所有的访问器接口的引用都可以从DataRabbit的根(“Root”)获得,在DataRabbit中,这样的根有两个,一个是IDataAccesser接口,另一个是TransactionScope。
6.一个根(“Root”)实例就对应着一个数据库。也可以这么说,针对一个特定的数据库,我们的应用只需要维护一个DataRabbit Root即可。
7. DataRabbit提供的所有的访问器(如IOrmAccesser)都可以在两种环境中工作:事务环境和非事务环境。这是由所有的访问器都继承了的ItransactionAccesser这个接口体现出来的。
8.任何一个访问器实例,如果在非事务环境中工作,那么它就是无状态的,DataRabbit将以Singleton的模式提供它的实例;如果访问器实例工作于事务环境中,那么它就是有状态的,并且它的生命期将随事务的结束而结束,DataRabbit以“Single Call”的模式提供它的实例。
三.DataRabbit中的ORM理念
DataRabbit所采用的ORM理念非常单纯、简单,其主要特点如下:
1.ORM仅仅对单表进行操作,不支持多表联合访问。对于多表联合访问的ORM解决方案,我还没有一个好的主意。
2.数据库中的一个数据表Table就对应着一个Entity Class定义,它们之间是一对一的映射关系。
(1) 为了省去不必要的麻烦,Entity Class的类名最好与对应的Table的名字完全一致。这样DataRabbit可以方便地根据Entity Class的名字找到数据库中对应的表,或者反过来。
(2) Table中的每个列对应着Entity Class中的一个属性,列和属性的名字要求完全一致,并且,它们的类型是匹配的。
(3) Table中的一条记录就对应着一个Entity Object。
3.ORM数据访问操作的定义不是位于Entity Class中,而是定义于专门的ORM访问器(IOrmAccesser)中。从这个意义上来说,Entity Class更像是一个仅仅封装了数据的结构,而不是一个类。
4.ORM访问器采用泛型和反射技术实现,这样,DataRabbit只需要提供一个ORM访问器类,便可以对数据库中的所有表进行ORM访问。
5.ORM访问器通过泛型参数来标志要访问哪个表。泛型参数还有一个好处是,所有的ORM访问操作都是强类型的。
6.使用Filter来表示单个的查询条件。ORM的一个非常重要的目的,就是屏蔽所有的SQL语句,所以Sql条件子句也需要被抽象建模。
7.使用IFilterTree接口来抽象复杂的多个查询条件的组合。
四、DataRabbit对N层架构提供支持
DataRabbit在设计实现的时候,就考虑了如何更好的支持系统架构,所以,DataRabbit可以非常平滑无缝地融合到3层/N层架构中。关于这方面的详细介绍可参见:DataRabbit 轻量的数据访问框架(12)-- 将DataRabbit融入架构