Nibernate映射配置,简单记法,配置说明。

学时主要是看的博客和文档

博客地址 http://www.cnblogs.com/GoodHelper/archive/2011/02/14/nhiberante_01.html 本文中部分代码和图便是从这里复制过来的。

 

说出来有点丢人,一直只是会照猫画虎的配,理解总是差了一线,但想找到”规律“,再一次瞪眼过程中,终于把那一线过了,再之后就不用记什么,闭着眼都能配了。

这里用文字,颜色,少量的文档说明,结合实例,解析每种配置实例。

相信对刚学习hibernate的同学会有帮助。

 

总结如下

基本映射就不多说了 属性生成器搞定,主键必要时再查,联合主键很少会用到。

多对一映射

PS 大学学数据库是学过外键的,但.NET的培训和我几个上司的建议是不用外键,不过必要的时候我还是加了点……还加了级联和触发器

因为很少用,刚开始接触hibernate,外键一段时间还比较晕,可能有和我一样晕的

这里补充

一句话:外键表的外键是主键表的主键,结合下面的图,很好记,主外键关系,一般是多对一关系,分主键表,和外键表,外键表为多,主键表为一。

举例

stuent是外键表,class是主键表

public class Class
{
public virtual int? ID { get; set; }

public virtual string Name { get; set; }
}

public class Student
{
public virtual int? ID { get; set; }

public virtual string Name { get; set; }

public virtual Class Class { get; set; }
}

name属性名,class主键表对应的类,colum外键表的外键,property_ref 外键表的外键对应类的属性,默认为主键。

闭着眼睛写

映射关系为 :本类型Student的属性class ,对应的类型为Class,对应关系,本类型(Student)对应的表(student)的外键字段ClassID值=Class类的主键属性ID的值

<class name="Student">

<many-to-one name="class"  class="Class" column="ClassID" property-ref="ID"/>

</class>

这是详细的写法,可以加深理解。

默认值可以简写为

 <many-to-one name="Class" column="ClassID"/>

简写是因为有默认值

class(可选 - 默认是通过反射得到属性类型): 关联的类的名字,反射可以找到对应的类型

property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。 就是说 关联的如果是对方的主键就可以不写本项

 

下面是文档的原话

property-ref属性只应该用来对付老旧的数据库系统, 可能有外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况下。 这是一种十分丑陋的关系模型。比如说,假设Product类有一个惟一的序列号, 它并不是主键。(unique属性控制NHibernate通过SchemaExport工具生成DDL的过程。) 

但若property-ref指向对方的主键就不是丑陋的关系模型了。

 

一对多

还是之前的关系图,与多对一对应

public class Student
    {
        public virtual int? ID { get; set; }

        public virtual string Name { get; set; }
    }

    public class Class
    {
        public virtual int? ID { get; set; }

        public virtual string Name { get; set; }

        public virtual IList<Student> Students { get; set; }
    }

一个班级可能有多个学生,学生是个集合ILIST

一对多关系 和 一对一关系中,一的一方,与其他类对应的属性(字段)默认且必须为该类型的ID(表的主键),这个例子为Class类的ID。

本类型(Class)的主键ID 1——m  一对多的集合(IList<Student>)里每个元素(Students)所对应表(Student)的外键(ClassID)

 <class name="Class" table="T_Class" lazy="true" >
    <id name="ID" type="int" column="ClassID">  这个ClassID只是配置Class类的主键
      <generator class="native"/>
    </id>

 <bag name="Students">
      <key column="ClassID"/>  这个ClassID实际是指Student类对应的Student表的字段。
      <one-to-many class="Student"/>
    </bag>

</class>

 

一对多和多对一就此结束,只有一对多,或只有多对一,为单向,都有则为双向,双向就不多说了,结合一对多和多对一便可以得到结果。

一对一

还是上面那句

一对多关系 和 一对一关系中,一的一方,与其他类对应的属性(字段)默认且必须为该类型的ID属性(表的主键)

补充 一的一方指主动配置的一方,也就是映射文件里有one-to-one配置的一方。

 

一、单向主键关联映射 

这种关系关联配置上没什么新东西,主要是主键的配置

主键关联不需要额外的表字段;如果两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!

<class name="Person" table="PERSON">
    <id name="Id" column="PERSON_ID">
        <generator class="foreign">
            <param name="property">Employee</param>  ,主键值 配置为通过外键查询,Person的主键值=Exmloyee类的主键值
        </generator>
    </id>
    ...
    <one-to-one name="Employee"
        class="Employee"
        constrained="true"/>  映射关系:无视上面的主键配置,这节的意思是,Person的主键Id=属性Employee的主键,one-to-one 也有property-ref这项,如果是主键则可省,唯一主外键一对一映射就设置了这项。 
</class>

上面为单向一对一。

双向只要在Employee类里加Person属性,映射里添

<one-to-one name="Person" class="Person"/>

就OK了,Emplyee的主键ID=Employee类中Person属性的ID。

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/> 也可以实现相同的效果,unique="true"表示是一对一,column="PERSON_ID"表示是Employee的PERSON_ID 对应的Person类的主键。

唯一外键关联映射

单向。

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>

如果在Person的映射加入下面几句,这种关联就是双向的:

<one-to-one name="Employee" class="Employee" property-ref="Person"/>
Person类主键ID=Employee类的Person属性的主键ID


多对多 hibernate并不推荐配置多对多,实际上多对多是通过第三张表作为中间表实现关联的
多对多的配置,完全可以自配置表1和表2 表2二表3,这样,实现表1和表3的多对多关系。 这在EF里是显式的多对多。
而下面这种直接配置多对多关系,在EF对映的是隐式的多对多。

懂单向的多对多,双向的也是一个道理
多对多,关系,主动配置的一方,默认为ID属性(表的主键)。

User(T_User的主键ID(UserID)=T_User_RoleUserID,T_User_RoleRoleID=Role(Role表)表的主键ID(RoleID)
 <many-to-many class="Role" column="RoleID"/> 与上面的类似

//这个ROLE,默认关联ROLE的ID(主键)
之前的某些配轩,是主键则可以省略不写,不是主键则添加 property-ref配置,不过这个我没试过。
<class name="User" table="T_User" lazy="true" >
    
<id name="ID" type="int" column="UserID"> 这是User类配置的主键,与下面的关系配置无关,烟雾弹。
      
<generator class="native"/>
    
</id>

    
<bag name="Roles" table="T_User_Role">
      
<key column="UserID"/>
      
<many-to-many class="Role" column="RoleID"/>
    
</bag>
    
  
</class>


posted @ 2013-06-12 01:10  cclient  阅读(683)  评论(0编辑  收藏  举报