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-to-one元素定义的。
None.gif < one-to-one
None.gif    
name ="propertyName" (1)
None.gif    class
="ClassName" (2)
None.gif    cascade
="all|none|save-update|delete" (3)
None.gif    constrained
="true|false" (4)
None.gif    outer-join
="true|false|auto" (5)
None.gif    property-ref
="propertyNameFromAssociatedClass"  (6)
None.gif    access
="field|property|ClassName" (7)
None.gif
/>
None.gif

  以下是对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 用来访问属性的策略

本文所涉及的类说明: img2.JPG
其中BizObject、User、ObjectBroker、Sessions等四个类就是 NHibernate学习笔记(一):初识NHibernate这篇文章定义的。
Student类和NativePlace类是一对一的双向关联关系:类Student通过属性NativePlace关联类NativePlace;类NativePlace通过属性Student关联类Student。

类Student的代码如下:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
None.gif
namespace  NHibernateTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class Student : User
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
fields#region fields
InBlock.gif        
private NativePlace objNativePlace;
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
constructors#region constructors
InBlock.gif        
public Student()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            objNativePlace 
= new NativePlace();
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Student(int StudentID) : base(StudentID) dot.gif{ }
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
properties#region properties
InBlock.gif        
public NativePlace NativePlace
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return objNativePlace;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                objNativePlace 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
methors#region methors
InBlock.gif        
public bool addNewStudent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.NativePlace.Student = this;
InBlock.gif                
this.Create();
InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public bool deleteStudent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.NativePlace.Student = this;
InBlock.gif                
this.Delete();
InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public bool updateStudent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.NativePlace.Student = this;
InBlock.gif                
this.Update();
InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

  在每次操作Student对象时,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果没写这一行运行时会出现“could not find class:NativePlace”(我就在写卡了好久)

类NativePlace的代码如下:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
None.gif
namespace  NHibernateTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class NativePlace : BizObject
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
fields#region fields
InBlock.gif        
private int intNPID;
InBlock.gif        
private string strCity;
InBlock.gif        
private string strProvince;
InBlock.gif        
private Student objStudent;
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
properties#region properties
InBlock.gif        
public int NPID
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return intNPID;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                intNPID 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Student Student
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return objStudent;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                objStudent 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string Province
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return strProvince;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                strProvince 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public string City
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return strCity;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                strCity 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

  这两个类的定义相对于User类没有什么太大的区别,接下来介绍两个类的配置文件。

  从UML来看,类NativePlace与类User之间是集合(构成)关系,即类NativePlace属于类Student的一部分,但不能独立存在,也就是说类NativePlace是依赖于类User的。

数据库脚本:
None.gif -- 表Users:用于保存Student对象
None.gif
Create   Table   [ Users ]
None.gif(
None.gif  
[ ID ]   int   identity ( 1 , 1 constraint  PK_UserID1  Primary   Key ,
None.gif  
[ UserName ]   varchar ( 20 not   null ,
None.gif  
[ Password ]   varchar ( 20 not   null
None.gif)
None.gif
None.gif
-- 表NativePlace:用于保存NativePlace对象
None.gif
Create   Table  NativePlace
None.gif(
None.gif  
-- 表NativePlace与表Users通过主键关联,则需保证两表的主键名一致
None.gif
  ID  int   Constraint  PK_NativePlaceID  Primary   Key ,    
None.gif  Province 
varchar ( 50 ),
None.gif  City 
varchar ( 50 )
None.gif)

类Student的映射文件:
None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< hibernate-mapping  xmlns ="urn:nhibernate-mapping-2.0" >
None.gif  
< class  name ="NHibernateTest.Student,NHibernateTest"  table ="Users" >
None.gif    
< id  name ="UserID"  column ="ID"  type ="Int32"  unsaved-value ="0" >
None.gif      
< generator  class ="identity" />
None.gif    
</ id >
None.gif    
< property  name ="UserName"  column ="UserName"  type ="String"  length ="20" />
None.gif    
< property  name ="Password"  column ="Password"  type ="String"  length ="20" />
None.gif    
None.gif    
< one-to-one  name ="NativePlace"  class ="NHibernateTest.NativePlace,NHibernateTest"  cascade ="all"   />
None.gif  
</ class >
None.gif
</ hibernate-mapping >
None.gif

类NativePlace的映射文件:
None.gif <? xml version="1.0" encoding="utf-8"  ?>
None.gif
< hibernate-mapping  xmlns ="urn:nhibernate-mapping-2.0" >
None.gif  
< class  name ="NHibernateTest.NativePlace,NHibernateTest"  table ="NativePlace" >
None.gif    
< id  name ="NPID"  column ="ID"  type ="Int32"  unsaved-value ="0" >
None.gif      
< generator  class ="foreign" >
None.gif        
< param  name ="property" > Student </ param >
None.gif      
</ generator >
None.gif    
</ id >
None.gif    
< property  name ="Province"  column ="Province"  type ="String"  length ="50" />
None.gif    
< property  name ="City"  column ="City"  type ="String"  length ="50" />
None.gif    
None.gif    
< one-to-one  name ="Student"  class ="NHibernateTest.Student,NHibernateTest"  cascade ="all"  constrained ="true" ></ one-to-one >
None.gif  
</ class >
None.gif
</ hibernate-mapping >
None.gif
注意:如果采用<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>

接下来是测试类:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.ComponentModel;
None.gif
using  System.Data;
None.gif
using  System.Drawing;
None.gif
using  System.Text;
None.gif
using  System.Windows.Forms;
None.gif
None.gif
namespace  NHibernateTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public partial class frmStudent : Form
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public frmStudent()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            InitializeComponent();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        Student objStudent;
InBlock.gif
InBlock.gif        
//Add New Student
InBlock.gif
        private void button1_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            objStudent 
= new Student();
InBlock.gif
InBlock.gif            objStudent.UserName 
= "jailu";
InBlock.gif            objStudent.Password 
= "123";
InBlock.gif            objStudent.NativePlace.Province 
= "FuJian";
InBlock.gif            objStudent.NativePlace.City 
= "LongYan";
InBlock.gif
InBlock.gif            
if (objStudent.addNewStudent())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"UnSuccess");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//Update
InBlock.gif
        private void btnUpdate_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            objStudent.UserName 
= "Update UserName";
InBlock.gif            objStudent.NativePlace.Province 
= "Update Province";
InBlock.gif
InBlock.gif            
if (objStudent.updateStudent())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"UnSuccess");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//Delete
InBlock.gif
        private void btnDelete_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (objStudent.deleteStudent())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"UnSuccess");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

  所有的类和映射文件都写好了,运行...成功.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值