zoukankan      html  css  js  c++  java
  • 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>


  • 相关阅读:
    Maximum sum
    走出迷宫
    取石子游戏
    全排列
    BZOJ3456 城市规划
    【SHOI2016】黑暗前的幻想乡
    【AHOI2012】信号塔
    HDU5730 Shell Necklace
    线性常系数齐次递推关系学习笔记
    矩阵树定理学习笔记
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/3132381.html
Copyright © 2011-2022 走看看