关于orm实体映射的感想 (object /relational mapper )
2005-05-29 njbaige/白鸽 于苏州
what orm?
object /relational mapper
why orm
一般的数据库访问是建立于传统的数据库访问模型的基础之上,
即是connection,command等对象,通过sql语句与数据库交互,并返回结果
现在.net下面的数据库访问框架已经到了ado.net 时代,ado.net 的访问方式
详见msdn的相关文档,这不是本文讨论的重点。但是要说明的是,在.net 环境
下的数据访问,都得要和ado.net打交道,那个是最底层得东西,我们今天谈的
数据库映射框架底层也是基于ado.net的访问模式,只是他们进行了很有效的封装
是得对数据库的操作从传统的sql模式,转换为基于对象的模式。
使业务逻辑与数据层分离,减少之间的藕合性,让系统开发对数据库透明
目前在网络上大家可以找到好几种持久层,其实各个持久层的思想都是相同的,只是在实现的方式上,
还有一些细节功能上有差异,每个持久层都有独特之处或是不足之处
how orm
实体映射:将数据库中的实体(一般是一张表)映射为类,对数据库的操作就
直接转换为对这些实体的操作:包括新,增,删,改等。采用实体的操作,会使我们对数据
库访问时,更方便,减少很多不必要的代码
关系映射:数据库中多个表之间会有相互的关系,怎样把这些关系也反映到映射好的类中
这就是关系映射,不过相比实体映射,关系映射实现起来更难,这也是评估不同orm好坏的
一个重要因素
高级查询:在数据库操作中,用得最多的是数据获取(retrieve)。查询条件也是很多样,会
有关联查询的情况,获取的结果也是要定制的,而不是简单的每个表的所有字段。
这点也是orm实现最关键的地方,各自实现的方式不同,而且有的用起来也很麻烦,不友好。
感觉还不如直接采用sql语句来的方便。这点nhibernate继承了hibernate的长处,采用hql
查询语言,功能最为强大。其他的orm 就不是很方便了。个人觉得还有必要保留sql语句接
口,返回table对象也是有不错的。
事务处理:在数据可靠性要求很高的时候,需要引入事务。由于ado.net 中对事务的支持
很好,所以在orm实现起来也是很棒的,一般的框架都支持这样的事务。
实体类和操作类的生成: orm说到底就是帮我们生成了一个功能强大的数据库访问类,
里面包括实体对象类,实体操作类等,实现了这样的思想,在代码生成上也需要友好,方便
才能为大众所用。所以一个优秀的orm框架需要搭配一个好的代码生成工具。目前一部分框架都有的,
支持直接同数据库连接,选择要生成的数据表,直接生成cs文件,编译成dll文件,直接导入到工程中就能用啦,
是不是很酷~(不过有的orm框架需要一些配置文件,也有生成的哦)
数据访问实现方式:对实体对象的获取,更新保存至数据库,在orm的底层都需要通过
连接来实现(不管是sql连接还是oledb 连接,还是oracle连接 ),他们实现的方式也有不同
这决定了我们在代码中的操作方式也不同。一种是通过一个manage类来实现,就像nhibernate、orm.net等,
这样的有点是连接操作效率更高,公用一个连接操作实体,缺点是我们使用起来不是很方便,
不是完全符合对象映射的构想,每次操作都得取找那个manage,麻烦;还有一种是直接放到实体类中,
也就是每一个实体类中都封装好了save,del等数据访问方法,要操作直接调用,就不要再去麻烦第三者了~
目前用过几个orm框架,下面是主要操作方式的学习笔记:
一 . orm.net 下载url:http://www.olero.com/ormweb/index.aspx
一个国外的orm框架,主要是生成代码工具很酷,才试用的。帮助文件也全,不过为e文的。
启动工具,连接至sql server(好像它只支持sql server,用的是system.data.sqlclient )
,显示出数据库中的每一张表和相应的关系,选择要生成的实体对象,配置文件路径和cs类名之后,
代码就出来了。就一个dll(外带一个连接配置文件,也可以不用,在代码里面赋值就ok)去看了里面的具体内容,
实体映射,事务处理是没问题的,在数据的复杂查询上,采用了自定义的一个查询条件类,
支持很复杂的查询条件(不过感觉开始用起来比较难上手)
二 smartpersistencelayer 下载url;http://www.cnblogs.com/tintown/category/12787.html
附很详细的帮助文档和实例
简称spl,最新版本3.1 , 听棠大哥的作品,也是目前国产最棒的orm映射框架,以郭先尧的xxmm.net为基础做的。
(不是帮他打广告,而是里面的功能确实很cool,不过也有不是很完美的地方-感觉)
支持sql server(system.data.sqlclient)、access(system.data.oledb)、oracle(system.data.oracleclient)、
informix (odbc连接方式)
提供“并发处理”、“异构数据库事务处理”、“多帐套”、“实体克隆”、“top功能”等解决方案。
有代码生成工具 smartrobot
配置文件:是采用config/databasemap.xml ,设置数据库的连接参数
o/r mapping 采用config/classmap.xml ,设置数据库中表字段和实体类之间的对应关系
基本的实体操作 :
实体类继承于entityobject,具父类为spl中的一个public abstract类,只要具体的实体类继承后,
实体类就拥有了save(),retrieve(),delete()的实体操作功能,无需借用manage类来实现
如:
studententity student=new studententity(); //实体化一个学生对象
//以下进行属性赋值
//student.id=1; //此为自动增长,spl会自动获取
student.no=” 200401”;
student.name=”张三”;
student.birthday=datetime.parse(“1979-01 -22”);
student.grade=2;
student.score=580;
student.save();
是不是不用串sql语句了?
criteria(标准)操作:对复杂条件的,返回值为实体对象集合的操作
采用几个criteria(标准)对象实现
retrievecriteria(获取标准)
updatecriteria (更新标准)
deletecriteria(删除标准)
retrievecriteria rc=new retrievecriteria(typeof(studententity)); //实例化
condition c=rc.getnewcondition(); //实例化一个条件
c.addequalto(studententity.__grade,2); //二年级条件
c.addmatchprefix(studententity.__name,’刘’); //匹配’刘’字开头
c.orderby(studententity.__no); //按学号排
datatable dt=rc.asdatatable() ; //以datatable方式返回
entitycontainer ec=rc.asentitycontainer(); //以实体集合的形式返回,然后在集合中操作entity。
有点类似rowcollection
rc.asentity(); //返回实体集合中的第一个对象
rc.top=20; 可以返回前20条记录哦
但是在复杂的表间连接,嵌套查询做得不够,听棠大哥解释的是采用数据库中的视图来完成。
所以我现在对于很复杂的查询,还是采用sql传递,返回table的方式,这点有待改进。
不过也是所有orm要面对的难题哦~
三 nhibernate 下载url:http://nhibernate.sourceforge.net/
国外的一个orm映射框架。继承了java平台hibernate的血统,不过功能
有待完善,但应该算是开源的业内最权威的orm框架了(不知道是不是沾了hibernate的光~)
操作非常全面,规范。
开发的过程
1.新建一个将要持久化.net对象的表
2.构建一个需要被持久化的.net类
3.构建一个可以让nhibernate知道如何持久化对象属性的映射文件