NHibernate学习笔记(二):one-to-one关系映射
上一篇:NHibernate学习笔记(一):初识NHibernate
本文的内容:
1.介绍NH如何处理对象间one-to-ont的映射关系;
经验教训:
1.操作一对一关联关系中的一个对象时,得在程序中指定如何与另一个对象关联,如在Student类中写this.NativePlace.Student = this;
2.在为类写映射文件时,必须指定类的具体的名称空间,若则运行时会出现"找不到***映射文件"的问题;
这两点都困扰了我好长一段时间,应该要引起注意.
点击下载本文相关代码(可在上篇代码的基础上做修改)
one-to-one:
NH中处理一对一关联的方式有两种:
1.主键关联
2.惟一外键关联
本文使用主键关联处理一对一的关系。
主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!
持久化对象之间一对一的关联关系是通过one <one-to-one
<one-to-one
 name="propertyName"(1)
    name="propertyName"(1)
 class="ClassName"(2)
    class="ClassName"(2)
 cascade="all|none|save-update|delete"(3)
    cascade="all|none|save-update|delete"(3)
 constrained="true|false"(4)
    constrained="true|false"(4)
 outer-join="true|false|auto"(5)
    outer-join="true|false|auto"(5)
 property-ref="propertyNameFromAssociatedClass" (6)
    property-ref="propertyNameFromAssociatedClass" (6)
 access="field|property|ClassName"(7)
    access="field|property|ClassName"(7)
 />
/>
 
 using System;
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.Text;
using System.Text;

 namespace NHibernateTest
namespace NHibernateTest
 {
{
 public class Student : User
    public class Student : User
 {
    {
 fields
        fields

 constructors
        constructors

 properties
        properties

 methors
        methors
 }
    }
 }
}
 
在每次操作Student对象时,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果没写这一行运行时会出现“could not find class:NativePlace”(我就在写卡了好久)
类NativePlace的代码如下: using System;
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.Text;
using System.Text;

 namespace NHibernateTest
namespace NHibernateTest
 {
{
 public class NativePlace : BizObject
    public class NativePlace : BizObject
 {
    {
 fields
        fields

 properties
        properties
 }
    }
 }
}
 
这两个类的定义相对于User类没有什么太大的区别,接下来介绍两个类的配置文件。
从UML来看,类NativePlace与类User之间是集合(构成)关系,即类NativePlace属于类Student的一部分,但不能独立存在,也就是说类NativePlace是依赖于类User的。
数据库脚本: --表Users:用于保存Student对象
--表Users:用于保存Student对象
 Create Table [Users]
Create Table [Users]
 (
(
 [ID] int identity(1,1) constraint PK_UserID1 Primary Key,
  [ID] int identity(1,1) constraint PK_UserID1 Primary Key,
 [UserName] varchar(20) not null,
  [UserName] varchar(20) not null,
 [Password] varchar(20) not null
  [Password] varchar(20) not null
 )
)

 --表NativePlace:用于保存NativePlace对象
--表NativePlace:用于保存NativePlace对象
 Create Table NativePlace
Create Table NativePlace
 (
(
 --表NativePlace与表Users通过主键关联,则需保证两表的主键名一致
  --表NativePlace与表Users通过主键关联,则需保证两表的主键名一致
 ID int Constraint PK_NativePlaceID Primary Key,
  ID int Constraint PK_NativePlaceID Primary Key,    
 Province varchar(50),
  Province varchar(50),
 City varchar(50)
  City varchar(50)
 )
)
类Student的映射文件: <?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
 <class name="NHibernateTest.Student,NHibernateTest" table="Users">
  <class name="NHibernateTest.Student,NHibernateTest" table="Users">
 <id name="UserID" column="ID" type="Int32" unsaved-value="0">
    <id name="UserID" column="ID" type="Int32" unsaved-value="0">
 <generator class="identity"/>
      <generator class="identity"/>
 </id>
    </id>
 <property name="UserName" column="UserName" type="String" length="20"/>
    <property name="UserName" column="UserName" type="String" length="20"/>
 <property name="Password" column="Password" type="String" length="20"/>
    <property name="Password" column="Password" type="String" length="20"/>
 
    
 <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />
    <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />
 </class>
  </class>
 </hibernate-mapping>
</hibernate-mapping>
 
类NativePlace的映射文件: <?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
 <class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">
  <class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">
 <id name="NPID" column="ID" type="Int32" unsaved-value="0">
    <id name="NPID" column="ID" type="Int32" unsaved-value="0">
 <generator class="foreign">
      <generator class="foreign">
 <param name="property">Student</param>
        <param name="property">Student</param>
 </generator>
      </generator>
 </id>
    </id>
 <property name="Province" column="Province" type="String" length="50"/>
    <property name="Province" column="Province" type="String" length="50"/>
 <property name="City" column="City" type="String" length="50"/>
    <property name="City" column="City" type="String" length="50"/>
 
    
 <one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>
    <one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>
 </class>
  </class>
 </hibernate-mapping>
</hibernate-mapping>
 注意:如果采用<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">这种声明的话,请在之后指写相关联类的名字时请指出完整的类名(名称空间+类名)和程序集名:如<class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">和<one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>
注意:如果采用<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">这种声明的话,请在之后指写相关联类的名字时请指出完整的类名(名称空间+类名)和程序集名:如<class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">和<one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>
接下来是测试类:
 using System;
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.ComponentModel;
using System.ComponentModel;
 using System.Data;
using System.Data;
 using System.Drawing;
using System.Drawing;
 using System.Text;
using System.Text;
 using System.Windows.Forms;
using System.Windows.Forms;

 namespace NHibernateTest
namespace NHibernateTest
 {
{
 public partial class frmStudent : Form
    public partial class frmStudent : Form
 {
    {
 public frmStudent()
        public frmStudent()
 {
        {
 InitializeComponent();
            InitializeComponent();
 }
        }

 Student objStudent;
        Student objStudent;

 //Add New Student
        //Add New Student
 private void button1_Click(object sender, EventArgs e)
        private void button1_Click(object sender, EventArgs e)
 {
        {
 objStudent = new Student();
            objStudent = new Student();

 objStudent.UserName = "jailu";
            objStudent.UserName = "jailu";
 objStudent.Password = "123";
            objStudent.Password = "123";
 objStudent.NativePlace.Province = "FuJian";
            objStudent.NativePlace.Province = "FuJian";
 objStudent.NativePlace.City = "LongYan";
            objStudent.NativePlace.City = "LongYan";

 if (objStudent.addNewStudent())
            if (objStudent.addNewStudent())
 {
            {
 MessageBox.Show("Success");
                MessageBox.Show("Success");
 }
            }
 else
            else
 {
            {
 MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess");
 }
            }
 }
        }

 //Update
        //Update
 private void btnUpdate_Click(object sender, EventArgs e)
        private void btnUpdate_Click(object sender, EventArgs e)
 {
        {
 objStudent.UserName = "Update UserName";
            objStudent.UserName = "Update UserName";
 objStudent.NativePlace.Province = "Update Province";
            objStudent.NativePlace.Province = "Update Province";

 if (objStudent.updateStudent())
            if (objStudent.updateStudent())
 {
            {
 MessageBox.Show("Success");
                MessageBox.Show("Success");
 }
            }
 else
            else
 {
            {
 MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess");
 }
            }
 }
        }

 //Delete
        //Delete
 private void btnDelete_Click(object sender, EventArgs e)
        private void btnDelete_Click(object sender, EventArgs e)
 {
        {
 if (objStudent.deleteStudent())
            if (objStudent.deleteStudent())
 {
            {
 MessageBox.Show("Success");
                MessageBox.Show("Success");
 }
            }
 else
            else
 {
            {
 MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess");
 }
            }
 }
        }
 }
    }
 }
}
所有的类和映射文件都写好了,运行...成功.
本文的内容:
1.介绍NH如何处理对象间one-to-ont的映射关系;
经验教训:
1.操作一对一关联关系中的一个对象时,得在程序中指定如何与另一个对象关联,如在Student类中写this.NativePlace.Student = this;
2.在为类写映射文件时,必须指定类的具体的名称空间,若则运行时会出现"找不到***映射文件"的问题;
这两点都困扰了我好长一段时间,应该要引起注意.
点击下载本文相关代码(可在上篇代码的基础上做修改)
one-to-one:
NH中处理一对一关联的方式有两种:
1.主键关联
2.惟一外键关联
本文使用主键关联处理一对一的关系。
主键关联不需要额外的表字段;两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!
持久化对象之间一对一的关联关系是通过one
-to-one元素定义的。
 <one-to-one
<one-to-one name="propertyName"(1)
    name="propertyName"(1) class="ClassName"(2)
    class="ClassName"(2) cascade="all|none|save-update|delete"(3)
    cascade="all|none|save-update|delete"(3) constrained="true|false"(4)
    constrained="true|false"(4) outer-join="true|false|auto"(5)
    outer-join="true|false|auto"(5) property-ref="propertyNameFromAssociatedClass" (6)
    property-ref="propertyNameFromAssociatedClass" (6) access="field|property|ClassName"(7)
    access="field|property|ClassName"(7) />
/>
  以下是对one-to-one元素各属性的说明:
  1.name:属性的名字
  2.class:(可选 - 默认是通过反射得到的属性类型): 被关联的类的名字
  3.cascade:(可选) 表明操作是否从父对象级联到被关联的对象
  4.constrained:(可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响Save()和Delete()在级联执行时的先后顺序(也在schema export tool中被使用)
  5.outer-join:(可选 - 默认为 auto):当设置hibernate.use_outer_join的时候,对这个关联允许外连接抓取
  6.property-ref:(可选): 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键
  7.access:(可选 - defaults to property): NHibernate 用来访问属性的策略
本文所涉及的类说明:
其中BizObject、User、ObjectBroker、Sessions等四个类就是NHibernate学习笔记(一):初识NHibernate这篇文章定义的。
Student类和NativePlace类是一对一的双向关联关系:类Student通过属性NativePlace关联类NativePlace;类NativePlace通过属性Student关联类Student。
类Student的代码如下:
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text;
 namespace NHibernateTest
namespace NHibernateTest {
{ public class Student : User
    public class Student : User {
    { fields
        fields
 constructors
        constructors
 properties
        properties
 methors
        methors }
    } }
}
在每次操作Student对象时,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果没写这一行运行时会出现“could not find class:NativePlace”(我就在写卡了好久)
类NativePlace的代码如下:
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Text;
using System.Text;
 namespace NHibernateTest
namespace NHibernateTest {
{ public class NativePlace : BizObject
    public class NativePlace : BizObject {
    { fields
        fields
 properties
        properties }
    } }
}
这两个类的定义相对于User类没有什么太大的区别,接下来介绍两个类的配置文件。
从UML来看,类NativePlace与类User之间是集合(构成)关系,即类NativePlace属于类Student的一部分,但不能独立存在,也就是说类NativePlace是依赖于类User的。
数据库脚本:
 --表Users:用于保存Student对象
--表Users:用于保存Student对象 Create Table [Users]
Create Table [Users] (
( [ID] int identity(1,1) constraint PK_UserID1 Primary Key,
  [ID] int identity(1,1) constraint PK_UserID1 Primary Key, [UserName] varchar(20) not null,
  [UserName] varchar(20) not null, [Password] varchar(20) not null
  [Password] varchar(20) not null )
)
 --表NativePlace:用于保存NativePlace对象
--表NativePlace:用于保存NativePlace对象 Create Table NativePlace
Create Table NativePlace (
( --表NativePlace与表Users通过主键关联,则需保证两表的主键名一致
  --表NativePlace与表Users通过主键关联,则需保证两表的主键名一致 ID int Constraint PK_NativePlaceID Primary Key,
  ID int Constraint PK_NativePlaceID Primary Key,     Province varchar(50),
  Province varchar(50), City varchar(50)
  City varchar(50) )
)类Student的映射文件:
 <?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> <class name="NHibernateTest.Student,NHibernateTest" table="Users">
  <class name="NHibernateTest.Student,NHibernateTest" table="Users"> <id name="UserID" column="ID" type="Int32" unsaved-value="0">
    <id name="UserID" column="ID" type="Int32" unsaved-value="0"> <generator class="identity"/>
      <generator class="identity"/> </id>
    </id> <property name="UserName" column="UserName" type="String" length="20"/>
    <property name="UserName" column="UserName" type="String" length="20"/> <property name="Password" column="Password" type="String" length="20"/>
    <property name="Password" column="Password" type="String" length="20"/> 
     <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />
    <one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" /> </class>
  </class> </hibernate-mapping>
</hibernate-mapping>
类NativePlace的映射文件:
 <?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> <class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">
  <class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace"> <id name="NPID" column="ID" type="Int32" unsaved-value="0">
    <id name="NPID" column="ID" type="Int32" unsaved-value="0"> <generator class="foreign">
      <generator class="foreign"> <param name="property">Student</param>
        <param name="property">Student</param> </generator>
      </generator> </id>
    </id> <property name="Province" column="Province" type="String" length="50"/>
    <property name="Province" column="Province" type="String" length="50"/> <property name="City" column="City" type="String" length="50"/>
    <property name="City" column="City" type="String" length="50"/> 
     <one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one>
    <one-to-one name="Student" class="NHibernateTest.Student,NHibernateTest" cascade="all" constrained="true"></one-to-one> </class>
  </class> </hibernate-mapping>
</hibernate-mapping>
接下来是测试类:
 using System;
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.ComponentModel;
using System.ComponentModel; using System.Data;
using System.Data; using System.Drawing;
using System.Drawing; using System.Text;
using System.Text; using System.Windows.Forms;
using System.Windows.Forms;
 namespace NHibernateTest
namespace NHibernateTest {
{ public partial class frmStudent : Form
    public partial class frmStudent : Form {
    { public frmStudent()
        public frmStudent() {
        { InitializeComponent();
            InitializeComponent(); }
        }
 Student objStudent;
        Student objStudent;
 //Add New Student
        //Add New Student private void button1_Click(object sender, EventArgs e)
        private void button1_Click(object sender, EventArgs e) {
        { objStudent = new Student();
            objStudent = new Student();
 objStudent.UserName = "jailu";
            objStudent.UserName = "jailu"; objStudent.Password = "123";
            objStudent.Password = "123"; objStudent.NativePlace.Province = "FuJian";
            objStudent.NativePlace.Province = "FuJian"; objStudent.NativePlace.City = "LongYan";
            objStudent.NativePlace.City = "LongYan";
 if (objStudent.addNewStudent())
            if (objStudent.addNewStudent()) {
            { MessageBox.Show("Success");
                MessageBox.Show("Success"); }
            } else
            else {
            { MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess"); }
            } }
        }
 //Update
        //Update private void btnUpdate_Click(object sender, EventArgs e)
        private void btnUpdate_Click(object sender, EventArgs e) {
        { objStudent.UserName = "Update UserName";
            objStudent.UserName = "Update UserName"; objStudent.NativePlace.Province = "Update Province";
            objStudent.NativePlace.Province = "Update Province";
 if (objStudent.updateStudent())
            if (objStudent.updateStudent()) {
            { MessageBox.Show("Success");
                MessageBox.Show("Success"); }
            } else
            else {
            { MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess"); }
            } }
        }
 //Delete
        //Delete private void btnDelete_Click(object sender, EventArgs e)
        private void btnDelete_Click(object sender, EventArgs e) {
        { if (objStudent.deleteStudent())
            if (objStudent.deleteStudent()) {
            { MessageBox.Show("Success");
                MessageBox.Show("Success"); }
            } else
            else {
            { MessageBox.Show("UnSuccess");
                MessageBox.Show("UnSuccess"); }
            } }
        } }
    } }
}所有的类和映射文件都写好了,运行...成功.
 
                    
                     
                    
                 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号