zoukankan      html  css  js  c++  java
  • NHibernate学习笔记manytoone/onetomany/manytomany(转)

    本文的内容:
      介绍NH如何处理对象间many-to-one,one-to-many和many-to-many的双向映射关系(本文主要介绍了映射文件,对于类的生成可以跟据前两篇描述的方法生成);

    经验教训:

    相关类图:(下面的类图包含一对一,多对一,一对多和多对多)
    many-to-one:描述多对一的一种数据模型,它指定many一方是不能独立存在的,我个人认为many-to-one是NHB中保证数据有效性的最有用的一种映射,通过使用many-to-one能有效的防治孤儿记录被写入到数据表中。在本文描述的例子中,Student类和Classes类之间是多对一关系.

      通过many-to-one元素,可以定义一种常见的与另一个持久化类的关联。这种关系模型是多对一关联。(实际上是一个对象引用。)在映射文件中用many-to-one标签描述此种关系.
    <many-to-one
            
    name="propertyName"(1)
            column
    ="column_name"(2)
            class
    ="ClassName"(3)
            cascade
    ="all|none|save-update|delete"(4)
            outer-join
    ="true|false|auto"(5)
            update
    ="true|false"(6)
            insert
    ="true|false"(7)
            property-ref
    ="propertyNameFromAssociatedClass" (8)
            access
    ="field|property|ClassName"(9)
            unique
    ="true|false" (10)
    />

    1.name:属性名。指出many一方的类用哪个属性和one一方的类关联.
    2.column:字段名(可选).指出many一方的类对应的数据表用哪个列和one一方的类对应的数据表关联(两表之间存在外键关联);
    3.class:关联的类的名字(可选 - 默认是通过反射得到属性类型);
    4.cascade:指明哪些操作会从父对象级联到关联的对象(可选).cascade属性允许下列值:: all, save-update, delete, none. 设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。
    5.outer-join:当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取(可选 - 默认为 auto).outer-join参数允许下列三个不同值: auto(使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy) ),true(一直使用外连接来抓取关联),false(永远不使用外连接来抓取关联);
    6.update,insert:指定对应的字段是否在用于UPDATE 和/或 INSERT的SQL语句中包含。如果二者都是false,则这是一个纯粹的“外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到的,或者通过trigger(除法器),或者是其他程序(可选 - 默认为 true
    7.property-ref:指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键(可选).property-ref属性只应该用来对付老旧的数据库系统,可能出现外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况。这是一种十分丑陋的关系模型。比如说,假设Product类有一个惟一的序列号,它并不是主键;
    8.access:NHibernate 用来访问属性的策略(可选 - 默认为property
    9.unique:允许产生外键列唯一约束的数据库定义语言(DDL)(可选)

    那么关于Student的映射可能是:

    <many-to-one name="Classes" column="cID" unique ="true"/>

    只要在原Student.hbm.xml映射文件中添加many-to-one标签就可以了.

    对于Sturent类得添加一个属性Classes:Classes

    one-to-many:
    一对多也是一种常见的数据模型,在按范式设计的数据库中随处可见。在NHB中通过one-to-many可以非常方便的处理这种模型,同时NHB还提供了级联更新和删除的功能,以保证数据完整性。在本文描述的例子中,Classes类和Student类是一对多的关系.

    Classes类的映射文件:Classes.hbm.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
      
    <class name="NHibernateTest.Classes,NHibernateTest" table="Classes">
        
    <id name="ClassesID" column="ID" type="Int32" unsaved-value="0">
          
    <generator class="identity"/>
        
    </id>
        
    <property name="ClassesName" column="ClassName" type="String" length="50"/>

        
    <bag name="StudentList" cascade="all"  inverse="true">
          
    <key column="ID" />
          
    <one-to-many class="NHibernateTest.Student,NHibernateTest" />
        
    </bag>
      
    </class>
    </hibernate-mapping>

      如映射文件所示,one-to-many标签必须包含在标签bag中(个人理解:多嘛,就用一个包装起来~)
            bag标签的name属性指出Address对象用哪个属性和Student对象关联,inverse属性使collection不更新连接(总之,这个属性提高了性能,具体的情况请参考NHibernate的帮助文档).
      key标签的column属性指出了Address对象对应的数据表用哪个字段和Student对象对应的数据表关联
      one-to-many标签的class属性指出了Address和哪个对象关联.

    对于Classes类得创建一个StudentList : Student的属性,用来描述与Student对象的关系.

    many-to-many:多对多在数据库中也是常见的数据模型,像用户与组,用户与权限等。多对多关系需要通过一个中间表实现,element的就是读取这个中间表中某列的值。在本文的例子中,Student类和Subject类是多对多的关系.

      Student的映射可能是:

        <bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
          
    <key column="StudentID" />
          
    <many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
        
    </bag>

      在bag标签中,加入了一个table属性,它指定一个实现多对多的中间表

      完整的Student.hbm.xml源码如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
      
    <class name="NHibernateTest.Student,NHibernateTest" table="Users">
        
    <id name="UserID" column="ID" type="Int32" unsaved-value="0">
          
    <generator class="identity"/>
        
    </id>
        
    <property name="UserName" column="UserName" type="String" length="20"/>
        
    <property name="Password" column="Password" type="String" length="20"/>

        
    <!--Student类和NativePlace类是一对一的关系-->
        
    <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />

        
    <!--Student类和Classes类是多对一的关系-->
        
    <many-to-one name="Classes" column="cID" unique ="true"/>

        
    <!--Student类和Address类是一对多的关系-->
        
    <bag name="AddressList" cascade="all"  inverse="true">
          
    <key column="ID" />
          
    <one-to-many class="NHibernateTest.Address,NHibernateTest" />
        
    </bag>

        
    <!--Student类和Subject类是多对多的关系-->
        
    <bag name="SubjectList" table="r_Student_Subject" inverse="true" cascade="save-update" lazy="false">
          
    <key column="StudentID" />
          
    <many-to-many class="NHibernateTest.Subject,NHibernateTest" column="ID" outer-join="auto" />
        
    </bag>
      
    </class>
    </hibernate-mapping>

      Student类得添加类型为IList的属性SubjectList表示与类Subject的关系.

      由于Student的映射关系比较复杂,本文就再熬述它的CRUD操作

  • 相关阅读:
    C# 操作配置文件
    C# Excel操作类
    没有找到 mspdb100.dll 的解决办法
    工厂方法模式
    .Net互操作2
    The certificate used to sign “AppName” has either expired or has been revoked. An updated certificate is required to sign and install the application解决
    手机抓包xcode自带命令行工具配合wireshark实现
    expecting SSH2_MSG_KEX_ECDH_REPLY ssh_dispatch_run_fatal问题解决
    使用ssh-keygen设置ssh无密码登录
    远程复制文件到服务器
  • 原文地址:https://www.cnblogs.com/kedach/p/1283214.html
Copyright © 2011-2022 走看看