• NHibernate关联讲解


    代码
    Many-To-Many 双向关联
    1.双向N——N关联的两边都需要指定连接表的表名,外键列的列名。
    2.两个set元素table必须指定,并且必须相同。
    3.set元素的两个字元素:key和many-to-many都必须指定column属性,key和many-to-many分别制定本持久化类,关联类在连接表中的外键列名,因此两边的key与many-to-many的column属性交叉相同。
    例如:
    T_User表          T_User_Role        T_Role表
        Id     Int主键自增        UserId    User表id        Id    Int主键自增
       UserName     String 
    50        RoleId    Role表id        RoleName    String 50
    UserPassword     String 
    50                        
    User类:
    ―――――――――――――――――――――――――
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;
    namespace NHibernateTest.Model

        [Serializable]
        
    public  class User
        {
            
    private int _userid;

            
    public virtual int UserId
            {
                
    get { return _userid; }
                
    set { _userid = value; }
            }
            
    private string _username;

            
    public virtual string UserName
            {
                
    get { return _username; }
                
    set { _username = value; }
            }
            
    private string _userpassword;

            
    public virtual string UserPassword
            {
                
    get { return _userpassword; }
                
    set { _userpassword = value; }
            }
            
    private IList _roles;

            
    public virtual IList Roles
            {
                
    get { return _roles; }
                
    set { _roles = value; }
            }
            
    public User()
            {
                _userid 
    = 0;
                _username 
    = null;
                _userpassword 
    = null;
                _roles 
    = new ArrayList();

            }

        }
    }

    Role类:
    ―――――――――――――――――――――――
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;
    namespace NHibernateTest.Model
    {
        [Serializable]
        
    public class Role
        {
            
    private int _roleid;

            
    public virtual int RoleId
            {
                
    get { return _roleid; }
                
    set { _roleid = value; }
            }
            
    private  string _rolename;

            
    public virtual string RoleName
            {
                
    get { return _rolename; }
                
    set { _rolename = value; }
            }
            
    private IList _users;

            
    public virtual IList Users
            {
                
    get { return _users; }
                
    set { _users = value; }
            }
            
    public Role()
            {
                _roleid 
    = 0;
                _rolename 
    =null;
                _users 
    = new ArrayList();
            }

        }
    }

    User类映射文件User.hbm.xml:
    -----------------------------------------------------------------------------
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="NHibernateTest.Model.User,NHibernateTest.Model"
    table
    ="T_User">
        
    <id name="UserId" column="Id" type="Int32" unsaved-value="0">
          
    <generator class="native"/>
        
    </id>
        
    <property column="UserName" type="String" name="UserName" not-null="true" length="50" />
        
    <property column="UserPassword" type="String" name="UserPassword" not-null="true" length="50" />
        
    <bag name="Roles" table="T_User_Role" lazy="true">
         
    <!--指定本持久化类(User)在连接表(T_User_Role)中的外键列名UserId,也就是T_User_Role表的UserId -->
    <key column="UserId"/>
    <!--指定关联类(Role)在连接表(T_User_Role)中的外键列名RoleId -->
              
    <many-to-many class="NHibernateTest.Model.Role,NHibernateTest.Model" column="RoleId"/>
        
    </bag>
      
    </class>
    </hibernate-mapping>

    Role类映射文件 Role.hbm.xml:
    ---------------------------------------------------
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
      
    <class name="NHibernateTest.Model.Role,NHibernateTest.Model" table="T_Role">
        
    <id name="RoleId" column="Id" type="Int32" unsaved-value="0">
          
    <generator class="native"/>
        
    </id>
        
    <property column="RoleName" type="String" name="RoleName" not-null="true" length="50" />
        
    <bag name="Users" table="T_User_Role" lazy="true" inverse="true">
          
    <!--指定本持久化类(Role)在连接表(T_User_Role)中的外键列名,也就是T_User_Role表的RoleId-->
          
    <key column="RoleId"/>
          
    <!--指定关联类(User)在连接表(T_User_Role)中的外键列名-->
          
    <many-to-many class="NHibernateTest.Model.User,NHibernateTest.Model" column="UserId"/>
        
    </bag>
      
    </class>
    </hibernate-mapping>
    实现代码如下:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using NHibernateTest.Model;
    using NHibernate;
    using NHibernate.Cfg;
    using NHibernate.Tool.hbm2ddl;
    namespace NHibernateTest
    {
        
    /*  many-to-many和别的关联映射有所不同。
         *  例子中:Role和User没有直接的依赖关系,而是通过一张中间表完成。
         *  在删除User时一般不会要求删除Role,而是删除之间的关系
         * (即从中间表删除数据)。
         
    */
    public partial class Many_To_Many : System.Web.UI.Page
    {
      
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void TestAddRoleToUser_Click(object sender, EventArgs e)
    {
                Configuration config 
    = new Configuration();
                config.AddAssembly(
    "NHibernateTest.Model");
                ISessionFactory sessions 
    = config.BuildSessionFactory();
                ISession session 
    = sessions.OpenSession();
                ITransaction trans 
    = session.BeginTransaction();
                
    try
                {
                    User user 
    = session.Load(typeof(User), 4as User;
                    Role role 
    = session.Load(typeof(Role), 4as Role;
                    user.Roles.Add(role);
                    role.Users.Add(user);
                    session.Update(user);
                    trans.Commit();
                }
                
    catch
                {
                    trans.Rollback();
                    
    throw new Exception("失败!");
                }
                
    finally
                {
                    session.Close();
                }

    }
    //移除user和role的关联关系
    protected void TestRemoveRoleFromUser_Click(object sender, EventArgs e)
    {
                Configuration config 
    = new Configuration();
                config.AddAssembly(
    "NHibernateTest.Model");
                ISessionFactory sessions 
    = config.BuildSessionFactory();
                ISession session 
    = sessions.OpenSession();
                ITransaction trans 
    = session.BeginTransaction();
                
    try
                {
                    
    //移除user和role的关联关系
                    User user = session.Load(typeof(User), 5as User;
                    Role role 
    = session.Load(typeof(Role), 5as Role;
                    user.Roles.Remove(role);
                    role.Users.Remove(user);
                    session.Update(user);
                    trans.Commit();
                }
                
    catch
                {
                    trans.Rollback();
                    
    throw new Exception("失败!");
                }
                
    finally
                {
                    session.Close();
                }

     }
    //更新了与UserId=6关联的Role的RoleName名字
    protected void TestUpdateUserWithRole_Click(object sender, EventArgs e)
     {
                Configuration config 
    = new Configuration();
                config.AddAssembly(
    "NHibernateTest.Model");
                ISessionFactory sessions 
    = config.BuildSessionFactory();
                ISession session 
    = sessions.OpenSession();
                ITransaction trans 
    = session.BeginTransaction();
                
    try
                {
                     
    //更新了与UserId=6关联的Role的RoleName名字
                    User user = session.Load(typeof(User), 6as User;
                    ((Role)user.Roles[
    0]).RoleName = "UpdateRole";
                    session.Update(user);
                    trans.Commit();
                }
                
    catch
                {
                    trans.Rollback();
                    
    throw new Exception("失败!");
                }
                
    finally
                {
                    session.Close();
                }

      }
       
    //删除T_User表id=10的记录和删除了T_User_Role表的UserId=10的记录
       
    //跟踪Sql:go
      /* DELETE FROM T_User_Role WHERE UserId = @p0', N'@p0 int', @p0 = 10
         DELETE FROM T_User WHERE Id = @p0', N'@p0 int', @p0 = 10
        
    */
    protected void TestDeleteUserWithSetRole_Click(object sender, EventArgs e)
      {
                Configuration config 
    = new Configuration();
                config.AddAssembly(
    "NHibernateTest.Model");
                ISessionFactory sessions 
    = config.BuildSessionFactory();
                ISession session 
    = sessions.OpenSession();
                ITransaction trans 
    = session.BeginTransaction();
                
    try
                {
                    User user 
    = session.Load(typeof(User), 10as User;
                    session.Delete(user);
                    trans.Commit();
                }
                
    catch
                {
                    trans.Rollback();
                    
    throw new Exception("失败!");
                }
                
    finally
                {
                    session.Close();
                }

    }
            
    //添加了User,Role 以及User-Role的关系
    protected void TestAddUserAndRole_Click(object sender, EventArgs e)
     {
                Configuration config 
    = new Configuration();
                config.AddAssembly(
    "NHibernateTest.Model");
                ISessionFactory sessions 
    = config.BuildSessionFactory();
                ISession session 
    = sessions.OpenSession();
                ITransaction trans 
    = session.BeginTransaction();
                
    try
                {
                    User user 
    = new User();
                    user.UserName 
    = "222";
                    user.UserPassword 
    = "222";   
                    Role role 
    = new Role();
                    role.RoleName 
    = "秘书"
                    role.Users.Add(user);
                    user.Roles.Add(role);
                    session.Save(user);
                    session.Save(role);
                    trans.Commit();
                }
                
    catch
                {
                    trans.Rollback();
                    
    throw new Exception("失败!");
                }
                
    finally
                {
                    session.Close();
                }
            }
        }
    }







    One-To-Many(单项关联1-N)
    因为集合属性都需要保存到另一个数据表中,所以保存集合属性表必须必须包含一个外键列,用于参照主键列。该外键列通过在
    <Set/>等集合元素中使用<key…/>子元素column来映射。不管使用那种集合,使用<bag../>元素都将映射成无序集合。集合属性对应的表没有主键。
    对于1—N的单向关联,需要在1的一端增加对应的集合映射元素。与映射集合类似,必须为
    <set> ,<bag>等集合元素增加key子元素,用以映射关联外键列。
    one
    -to-many标签包含在标签bag/set中.bag标签的。inverse属性使collection不更新连接。
    key标签的column属性指出了在另一个数据库表中加入外键,来关联本类。

    T_Parent        T_Child
    Id    Int主键自增        ChildId    Int自增
    Name    String        Name    String 
                ParentId    T_Parent表Id

    Many-To-One
    many
    -to-one:描述多对一的一种数据模型,它指定many一方是不能独立存在的,我个人认为many-to-one是NHB中保证数据有效性的最有用的一种映射,通过使用many-to-one能有效的防治孤儿记录被写入到数据表中。
    <many-to-one
             name
    ="propertyName"(1)
              column
    ="column_name"(2)
              
    class="ClassName"(3)
              cascade
    ="all|none|save-update|delete"(4)
             unique
    ="true|false" (10)
     
    />
    .name:属性名。指出many一方的类用哪个属性和one一方的类关联.
    .column:字段名(可选).指出many一方的类对应的数据表用哪个列和one一方的类对应的数据表关联(两表之间存在外键关联);
    class:关联的类的名字(可选 - 默认是通过反射得到属性类型);
    .cascade:指明哪些操作会从父对象级联到关联的对象(可选).cascade属性允许下列值:: all, save-update, delete, none. 设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。
    5.unique:允许产生外键列唯一约束的数据库定义语言(DDL)(可选)
  • 相关阅读:
    CentOS7 常用命令集合
    Microsoft Visual C++ 14.0 is required问题的解决或warning: Debugger speedups using cython not found
    microsoft visual c++与microsoft visual net 版本对应关系
    [Python爬虫] 之三十一:Selenium +phantomjs 利用 pyquery抓取消费主张信息
    Selenium support for PhantomJS has been deprecated, please use headless
    PyDev:warning: Debugger speedups using cython not foun
    文本相似性计算总结(余弦定理,simhash)及代码
    解决 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type的问题
    Java Web学习总结-文件下载
    jsp button提交表单
  • 原文地址:https://www.cnblogs.com/hubcarl/p/1706390.html
Copyright © 2020-2023  润新知