O/R Mapping框架首选在Java世界流行,随后在.NET推出后,一些在Java上的著名的O/R Mapping框架,如Hibernate被移植到了.NET下。另外一些原创的.NET O/R Mapping框架也被逐步开发出来。下面就来介绍几个重要O/R Mapping框架。
1.NHibernate
NHibernate应该是大家最熟悉的.NET O/R Mapping框架。它来自Java上著名且广泛使用的Hibernate。NHibernate采用XML文件配置的方式,为每个对象都需要提供一个映射文件。在定义了对象的数据结构和XML映射文件后,NHibernate就自动产生SQL语句,并确保对象提交到正确的表和字段中去,大量减少开发时人工使用SQL和ADO.NET处理数据的时间。NHibernate可以帮助消除或者包装那些针对特定数据库的SQL代码,并且把结果集从表格的表示形式转换到一系列的对象去。
下面是一个映射的例子:
(对象结构定义User.cs) public class User { public User() { } private string id; private string userName; private string password; private string emailAddress; private DateTime lastLogon; public string Id { get { return id; } set { id = value; } } public string UserName { get { return userName; } set { userName = value; } } public string Password { get { return password; } set { password = value; } } public string EmailAddress { get { return emailAddress; } set { emailAddress = value; } } public DateTime LastLogon { get { return lastLogon; } set { lastLogon = value; } } } (映射文件定义User.hbm.xml) <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> <class name="NHibernateWebDemo.Model.User, NHibernateWebDemo.Model" table= "users"> <id name="Id" column="LogonId" type="String" length="20"> <generator class="assigned" /> </id> <property name="UserName" column= "Name" type="String" length="40"/> <property name="Password" type="String" length="20"/> <property name="EmailAddress" type="String" length="40"/> <property name="LastLogon" type="DateTime"/> </class> </hibernate-mapping>
|
在定义了对象和XML映射文件后,就可以利用NHibernate来持久化对象到数据库了。
得到配置对象:
Configuration config=new Configuration(); |
得到会话工厂对象:
ISessionFactory factory = config.BuildSessionFactory(); |
得到会话对象:
ISession session = factory.OpenSession(); |
如果有必要,就启用事务对象:
ITransaction trans = session.BeginTransaction(); |
创建User的实例,保存到数据库中,并提交事务:
User obj=new User(); obj. UserName=”zyg”; session.Save(obj); trans.Commit(); |
2.Castle ActiveRecord
Castle是一个混合IoC(反转控制器)框架、O/R Mapping框架和Web MVC框架的一个开源项目(本书后面章节会详细谈到Castle)。目前,Castle已经发布了RC3,可以到http://www.castleproject.org/下载。
ActiveRecord是Castle项目基于NHibernate开发的一套O/R Mapping框架。与NHibernate的重要区别在于ActiveRecord无须HBM映射文件,使用Attribute来描述对象到数据库的映射关系,且ActiveRecord使用了Martin Fowler在《Patterns of Enterprise Application Architecture》中提到的Active Record模式来作为中心设计思想。
下面我们看看ActiveRecord的一个例子:
[ActiveRecord] public class User : ActiveRecordBase<User> { private int id; private string username; private string password; public User() { } public User(string username, string password) { this.username = username; this.password = password; } [PrimaryKey] public int Id { get { return id; } set { id = value; } } [Property] public string Username { get { return username; } set { username = value; } } [Property] public string Password { get { return password; } set { password = value; } } } |
在定义对象的结构后,就可以直接使用了:
初始化ActiveRecord:
XmlConfigurationSource source = new XmlConfigurationSource("appconfig.xml"); ActiveRecordStarter.Initialize( source, typeof(User) ); |
通过ActiveRecord自动在数据库中创建对应表:
ActiveRecordStarter.CreateSchema(); |
创建一个用户:
User user = new User("admin", "123"); user.Create(); |
修改一个用户的信息:
user.Username=”administrator”; user.Update(); |
3.iBATIS.NET
iBATIS.NET也是由Java中的著名的iBATIS框架移植过来的。这个框架有两个主要的组成部分:一个是SQL Maps,另一个是Data Access Objects。第一部分就是针对O/R Mapping的一种实现。但严格来说,iBATIS.NET并不算真正的O/R Mapping框架,它主要目的是在于系统模型对象与SQL之间的映射关系。也就是说,iBATIS.NET并不会为程序员在运行期自动生成SQL 执行。具体的SQL 需要程序员编写,然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定模型对象中。这种方式相对NHibernate更具灵活性,给开发人员更多的自由空间去控制映射的过程。下面我们来看一个例子。
创建一个数据表:
字段名称 |
数据类型 |
大 小 |
是否为空 |
PER_ID |
Long Integer |
4 |
No |
PER_FIRST_NAME |
nvarchar |
40 |
No |
PER_LAST_NAME |
nvarchar |
40 |
No |
PER_BIRTH_DATE |
DateTime |
8 |
Yes |
PER_WEIGHT_KG |
float |
8 |
Yes |
PER_HEIGHT_M |
float |
8 |
Yes |
定义一个实体类:
[Serializable] public class Person { private int id; private string firstName; private string lastName; private DateTime? birthDate; private double? weightInKilograms; private double? heightInMeters; public Person() { } public int Id { get { return id; } set { id = value; } } public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public DateTime? BirthDate { get { return birthDate; } set { birthDate = value; } } public double? WeightInKilograms { get { return weightInKilograms; } set { weightInKilograms = value; } } public double? HeightInMeters { get { return heightInMeters; } set { heightInMeters = value; } } } |
编写映射文件,在映射文件中书写SQL语句:
<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <alias> <typeAlias alias="Person" type="IBatisNetDemo.Domain.Person, IBatisNetDemo" /> </alias> <resultMaps> <resultMap id="SelectAllResult" class="Person"> <result property="Id" column="PER_ID" /> <result property="FirstName" column="PER_FIRST_NAME" /> <result property="LastName" column="PER_LAST_NAME" /> <result property="BirthDate" column="PER_BIRTH_DATE" /> <result property="WeightInKilograms" column="PER_WEIGHT_KG" /> <result property="HeightInMeters" column="PER_HEIGHT_M" /> </resultMap> </resultMaps> <statements> <select id="SelectAllPerson" resultMap="SelectAllResult"> select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON </select> <select id="SelectByPersonId" resultClass="Person" parameterClass="int"> select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON where PER_ID = #value# </select> <insert id="InsertPerson" parameterclass="Person" > <selectKey property="Id" type="post" resultClass="int"> ${selectKey} </selectKey> insert into Person ( PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M) values (#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#) </insert> <update id="UpdatePerson" parameterclass="Person"> <![CDATA[ update Person set PER_FIRST_NAME =#FirstName#, PER_LAST_NAME =#LastName#, PER_BIRTH_DATE =#BirthDate#, PER_WEIGHT_KG=#WeightInKilograms#, PER_HEIGHT_M=#HeightInMeters# where PER_ID = #Id# ]]> </update> <delete id="DeletePerson" parameterclass="Person"> delete from Person where PER_ID = #Id# </delete> </statements> </sqlMap> |
初始化SqlMap对象:
DomSqlMapBuilder d=new DomSqlMapBuilder(); SqlMapper sm=d.Configure("SqlMap.config"); |
得到所有数据:
sm. QueryForList(“SelectByPersonId”,null); |
添加一条数据:
Person p=new Person(); p.id=1; p. FirstName=”zyg”; sm.Insert(“InsertPerson”,p); |
4.其他的一些O/R Mapping框架
·Nbear框架中内置的O/R Mapping功能。
·Grove Develop Kit(http://www.grovekit.com/)。
·Base4.NET 不仅仅是一个O/R Mapping(http://www.base4.net/)。
·SubSonic 是最近非常流行和一个很特点的框架(http://www.subsonicproject.com/)。