听棠.NET

基于.NET的持久层SmartPersistenceLayer
免费职业锚定位测评
posts - 244, comments - 10184, trackbacks - 104, articles - 5
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

SmartPersistenceLayer之设计功能篇

Posted on 2004-11-08 12:35 听棠.NET 阅读(7168) 评论(28)  编辑 收藏 所属分类: SmartPersistenceLayer
 

SmartPersistenceLayer之设计功能篇

  持久层SmartPersistenceLayer以下都简称为SPL,目前版本为2.0.

持久层概念

       数据层透明

目前在网络上大家可以找到好几种持久层,其实各个持久层的思想都是相同的,只是在实现的方式上,还有一些细节功能上有差异,每个持久层都有独特之处或是不足之处,这本身是一个发展过程,SPL也不例外,我同样希望有朋友能提出问题,能让持久层更加完善。

持久层(下面我都以PL来代替持久层)是作为系统开发的一个低层平台,所有涉及的数据库操作通过PL来实现,使用O/R Mapping的方式使用业务对象与数据库进行分隔,因为从思想角度来看的话,业务逻辑本身与数据库不应该有太多的约束,业务逻辑是千变万化的,那么业务逻辑不应该受到数据库的牵制,因此系统采用什么样的数据库(SQL Server,Oracle),对于业务逻辑层面来看,那都是数据库,只要能实现关系型数据库的功能就可以。

所以,PL最根本的一个功能,就是使用业务逻辑与数据层分离,让系统开发对数据库透明。

SPL目前支持SQL ServerAccess,Oracle,对于SQLAccessSPL会自动产生sqlConnection,其他数据库采用OleDbConnection连接。这也是MS推荐的方式。

 

实体映射

ORM原理中我们可以理解到,为了让业务逻辑的开发与数据库能具有这种对应关系,采用Object Relational映射来实现,也就是在业务系统中定义“实体Entity”,那么通过一个XML文件实现EntityTable的映射,然后业务系统中对Entity的操作,通过PLXML映射来完成真正的数据库访问。

SPL中的Entity与其他PL不同的地方,SPL采用继承ObjectEntity的方式来实现Entity本身的增删改操作,这种实现方式更加对象化,更能站系统开发站在OO的层面上,目前SPL中提供EntityRetrieve(获取)Save(保存),Delete(删除)功能。在这些操作中,开发员真正意义上的面向对象开发、对数据层彻底透明,不需要任何一句SQL语句就实现多数据库操作。

这将解决SQL编写造成的开发速度慢、语句调试复杂、容易出错,扩展性差等不足。

 

关系映射

ORM的理论上,除了实体外,还有一个Relational功能,也就是用EntityEntity之间的关系来实现数据库里的表表关系。这种Relational具有相当的复杂度,网络上有些PL也实现了Relational,这应该是一个比较好的开始,具体的功能与效果我也没有偿试过。

由于这种复杂性,SPL中目前去掉了Relational功能,我需要更多的时间来考虑如何让系统开发对Relational更加方便。

也可能是这方面,使SPL比其他的PL要容易上手,容易理解。

 

SPL特性

SPL在完成以上实体功能的基础上,增加了一些特性,我简单介绍一下先,这些都会在后续的文档中发布。

标准Criteria

              Criteria是指标准,目前的SPL分为RetrieveCriteria(获取标准),UpdateCriteria(更新标准),DeleteCriteria(删除标准),这些标准也都是针对一个实体进行操作的。

              RetrieveCrietria(获取标准)

                     可以通过RetrieveCriteria进行一个实体的高级查询,比如定义查询条件,定义排序方式等,举个简单例子:

          目前有个StudentEntity实体,要实现“查询所有的姓刘的同学,并以学号进行排序”:

          RetrieveCriteria rc=new RetrieveCriteria(typeof(StudentEntity)); //实例化

                Condition c=rc.GetNewCondition();          //创建一个条件

             c.AddMatchPerfix(StudentEntity.Name,’’);   //这会生成name like ‘%’的查询

          rc.OrderBy(StudentEntity.No);              //这会生成order by No

          DataTable dt=rc.AsDataTable();             //这以DataTable的方式返回

          关于Condition类将在以后进行讲解,RetrieveCriteria提供多种返回方式,方便对返回结果进行操作,如果是进行数据绑定,则直接以DataTable返回;如果是要进行操作,则使用AsEntityContainer方式返回Entity集合.

       

        UpdateCriteria(更新标准)DeleteCriteria(删除标准)

               UpdateCriteria是产生Update table set Name=’xx’ where ….的语句

               DeleteCriteria 是产生Delete from table where …的语句

                使用方式类似于RetrieveCriteria ,将在以后文档中进行详细讲解

 

       事务处理

       事务处理可能是系统开发中最经常用到的了,SPL中的事务处理相当简单,前面介绍的那些操作都可以以事务的方式进行处理:

Transaction t=new Transaction();

t.AddSaveObject(ObjectEntity)

添加Entity的保存到事务中,根据EntityIsPersistence自动进行判断InsertUpdate

t.AddDeleteObject(ObjectEntity)

添加Entity删除到事务中

t.AddDeleteCriteria(DeleteCriteria)

添加删除标准到事务中

t.AddUpdateCriteria(UpdateCriteria)

添加更新标准到事务中

t.AddSqlString(sqlString,db)

添加SQL执行语句到事务中

t.Process()

执行事务提交,如果遇到错误,事务全部rollback.

 

Query高级查询

Query是一个功能强大的查询类,可以进行Entity之间的联合查询,也可以使用Query的一些静态进行数据库操作。

Query的联合查询功能目前支持内联接,没有实现左联接,由于查询本身是个最复杂的东西,所以在我的设计方案中,我一般是采用视图来进行联合查询。

Query. ProcessSql(sqlString,”db”)

静态执行SQL语句,对于一些SPL无法实现的功能,可以使用此SQL语句进行处理

Query还支持简单的汇总查询,具体功能在以后文档中进行讲解

      支持自动增长字段

       自动增长的字段,在SPL中不需要指明,会自动进行值增长,并马上返回到系统实体中,以便进行后继处理,比如新增了订单主档后,会把订单生成的ID返回到Entity中,以便于进行订单明细保存时使用。

       动态数据源配置

       默认情况下数据源会从XML配置文件里读里,系统也提供使用代码直接Add一个数据源连接。

多帐套支持

在大型系统中会使用到多帐套,也就是一些完全一样的表实体,只是数据源不同,这种我就称之为多帐套,SPL中支持多帐套,也就是所有的操作都可以在系统中手动设置databaseName,这样会更新到不同的数据库中。

内存存储

这个功能应该是目前国内市场上唯一的一个了。

对于一些维护型的数据,由于其数据量少,字段少,维护频率低,使用率高等特点,为了提高系统的整体性能,这些数据可以保存在内存中,减少数据库的访问,SPL中要使用此功能非常简单,只要要声明Entity时,指明”IsSaveToMemory=true”即可,这样,SPL在第一次获取后,会保存到内存中,以后的读取会自动从内存中获得,这个Entity的更新,比如Insert,Update,Delete等操作会根据IsSaveToMemory自动更新到内存,也就是对于开发员来说,这个功能是完全透明的。第二:内存存储也是支持多帐套的,也就是同样的Entity,如果是从不同的数据库取得的,会生成两个内存复本,以后的读取与修改也都是以自己的帐套为准的。

 

以上我是简单介绍了一个SPL的设计出发点与功能点,详细的介绍我将会在后继发布文档。

 

希望有兴趣的朋友,能对SPL提出意见,以便让SPL能更加完善。

 

                                                       听棠

                                                       200411

                                          MSN:tintown_liu@hotmail.com

Feedback

#1楼    回复  引用  查看    

2004-11-08 12:50 by yyanghhong      
does it support entity inherence? if I have two classes such as people and men, how do I write the code or XML file to define them?

#2楼    回复  引用  查看    

2004-11-08 13:08 by Unruled Boy(灵感之源)      
考虑过开源放到sf.net上吗?

#3楼 [楼主]   回复  引用  查看    

2004-11-08 13:32 by 听棠.NET      
关于继承我是这样理解的,如果那个父类确实也映射到数据库里的一个表,那么这个父类也定义为一个具体的Entity,如果那个父类不映射到一个具体的表,那么也就是这个类是个抽象类,所以可以定义为public abstract PeopleEntity :ObjectEntity
这个PeopleEntity是没有必要使用XML映射的,
然后这个抽象类可以供具体Entity类继承,这样就可以实现了。
具体的东西还是要具体分析。

#4楼    回复  引用    

2004-11-08 14:51 by jlzhou [未注册用户]
太高深了,偶看不懂了!

佩服楼上的功力!

加油啊!(油价又涨啦)

#5楼    回复  引用  查看    

2004-11-08 15:58 by QQ'Richer      
呵呵,每天重复的敲CRUD快敲晕了,期待着SPL早日发布,找了一下,国内的好用的这个东西还真不多见。。

#6楼    回复  引用  查看    

2004-11-08 20:11 by Yok      
关于继承我是这样理解的,如果那个父类确实也映射到数据库里的一个表,那么这个父类也定义为一个具体的Entity,如果那个父类不映射到一个具体的表,那么也就是这个类是个抽象类,所以可以定义为public abstract PeopleEntity :ObjectEntity
这个PeopleEntity是没有必要使用XML映射的,
然后这个抽象类可以供具体Entity类继承,这样就可以实现了。
具体的东西还是要具体分析。
================================
yyanghhong关心的不是继承会不会影响实体类被持久化的问题.
ORM里支持继承的好处是能很方便的实现多态的关联和查询.例如
RetrieveCriteria rc=new RetrieveCriteria(typeof(PeopleEntity));
这样的查询应该能返回符合条件的man和woman
或者Department类里有People的集合Members,可以往Members添加man或woman

#7楼 [楼主]   回复  引用  查看    

2004-11-08 21:08 by 听棠.NET      
Yok的意思我也明白了。对于这种父类,我想如果要在PL中定义,也不能完全以Entity来处理,因为父类不具备持久化,因此不能进行所谓的增删改,就如RetrieveCriteria(typeof(PeopleEntity))一样只是进行查询,还有Department中的People,我在想PL是否能做到这种功能,有其他的PL实现了吗?我想参考参考!!
从实现角度看,要从一个父类获取那些子类,这需要借助于XML映射。

#8楼    回复  引用  查看    

2004-11-08 22:54 by Yok      
XPO和nHibernate都可以,其他商业产品一般也可以的了
XPO和你的SPL比较相似
这里有源码
http://soft.0zones.com/SoftView/SoftView_12789.html

#9楼    回复  引用  查看    

2004-11-09 09:13 by Kozen      
to 听棠.NET :
看上去,你的实体映射方式是 one concrete class one table,为何不采用one class one table的方式?即一个具体类的数据通过jion几张有继承关系的表而获得。
另,SPL的内存存储功能对于集群服务器是如何考虑的呢?

#10楼 [楼主]   回复  引用  查看    

2004-11-09 09:27 by 听棠.NET      
关于“一个具体类join多张表”的意思我理解,我不知道这样做会带来多少好处,也就是在我们的系统开发中,大部分情况下是单表映射足够了,如果要映射多个表,好处就是能透明的处理多个表,不过,有关修改与删除,可能只要涉及到里面的一个表,我目前来看,觉得单表对应更能让开发员明确细节,还有这个功能在PL里实现可能比较麻烦,至少近期不会考虑吧.有必要的时候,我考虑考虑。

关于集群服务器,先得让我看一下概念:)水平有限:)
Kozen能否给点指示,对于集群服务器的话,你觉得内存存储应该如何实现吗?是否应该让PL去实现呢?

#11楼    回复  引用  查看    

2004-11-09 12:53 by yyanghhong      
so, if this framework doesn't support either inherence or aggregate, what is difference between it and data table. and I beceive that it doesn't support stored proceudre too.

I suggest that you take a look hibernate carefully, it has all of above features already, you would learn a lot from it. don't just coding, thinking is more important.

#12楼    回复  引用  查看    

2004-11-09 17:34 by Laser.NET      
http://www.cnblogs.com/laser_lu/archive/2004/10/27/57468.html
多参考参考,或许对你有帮助:)

#13楼    回复  引用  查看    

2004-11-09 17:35 by Laser.NET      
顺便讲一下,我对持久化的研究也比较感兴趣,如果我们在一个公司的话,可以多交流:)

#14楼    回复  引用  查看    

2004-11-10 09:12 by Kozen      
to 听棠.NET :
1. one class one table是Ambler提出的概念,他是PL的先驱,你可以阅读一下 www.ambysoft.com。其实这个概念在martin fowler的POEAA中也有描述,他称之为 Class Table Inheritance。
有什么好处,你看后便能清楚。

2. 集群服务指提供负载均衡或多机切换的服务器,从而提供更好的性能和稳定性。若你的PL使用在多个对等的应用服务器上,当一个应用服务器的缓冲更新时,你得通知其他的应用服务器,否则当客户端从未更新的应用服务器获取数据时会产生数据不一致。由于该功能并不是PL与生俱来的,所以其实现可以放在别的层面。但我个人认为可由PL层实现,因为你的缓冲也是由PL层管理的。

btw: 指示谈不上,只能说是交流一下。:)

#15楼 [楼主]   回复  引用  查看    

2004-11-10 11:00 by 听棠      
TO:Kozen
首先非常感谢你的宝贵意见,
1.这个在SPL的1.0版中是已经实现的,但是后来觉得实现上可能有问题,我在2.0中就删除了,下一版会考虑加进去的,主要是relation的处理使PL变的异常复杂:)
2.呵,这个实现起来确实有点困难,如何让一个服务器应用系统通知另一服务器应用系统呢?兄弟能否指点指点呢.能否给个实现方案.如果要让PL来实现的话,恐怕要写Windows服务吧.

#16楼    回复  引用    

2005-06-20 09:59 by clamphammer [未注册用户]
恩,就是实现了martin.fowler 企业架构设计模式中的一部分模式

#17楼    回复  引用    

2006-02-26 16:51 by Yng [未注册用户]
good

#18楼    回复  引用  查看    

2006-10-12 10:01 by 差劲的程序员      
我想问下spl能否对sql注入式攻击进行防范呢?还是要自己过滤危险动作?

#19楼    回复  引用  查看    

2006-10-27 09:11 by jhkmnm      
老大,我在做的时候老是提示没有找到相关的映射,能不能发个使用说明给我,
jhkmnm_123@163.com

#20楼    回复  引用    

2006-12-15 19:26 by Deng02 [未注册用户]
这个想法很不错,只是前一段时间看到一个NBear的系统,做得很不错,好像也在这个博客园上,可以看看,
如果可能,最好能在NBear的基础之上再去做些有用的事情,大家没有必要做些相同的工作。

#21楼    回复  引用  查看    

2007-02-13 14:06 by 仰天一笑      
希望听棠能够写一篇关于SPL完整的使用说明,SPL的下载,这样有利于我们的学习,也给SPL注入新的活力,如果听棠大哥利用空闲时间,写个小例子,我们这些坐观之客当感激不尽,哈哈。

#22楼    回复  引用  查看    

2007-02-13 15:39 by Arlen      
不知道听棠为什么要做些同学们都做过的事情呢?
实践中学习?

#23楼    回复  引用  查看    

2007-05-28 17:14 by yfz      
"我想问下spl能否对sql注入式攻击进行防范呢?还是要自己过滤危险动作?"
这个问题听棠大哥怎么不回答呢?我也很想知道!谢谢@

#24楼    回复  引用    

2007-08-23 10:28 by program [未注册用户]
学习了

#25楼    回复  引用  查看    

2007-09-12 17:11 by 念时      
签名,才看到SPl的文章,关注ing……

#26楼    回复  引用    

2008-03-22 21:37 by 挖土_0 [未注册用户]
2年多了,还是没有什么更新啊! 我感觉你的东西实在是很好用!给我节约了很多的时间!

#27楼    回复  引用    

2008-06-11 21:35 by 熊鹰 [未注册用户]
2 年前能设计出这样的持久层,真是相当不错,现在的LINQ也就是这个理念。

#28楼    回复  引用  查看    

2008-07-16 19:35 by 阿鹏      
楼上的,3年前.2004-11-08

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-09-06 15:59 编辑过