NHibernate學習筆記(二):one-to-one關係映射

本文的內容:
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.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
None.gif
namespace NHibernateTest
ExpandedBlockStart.gif
{
InBlock.gif    
public class Student : User
ExpandedSubBlockStart.gif    
{
ContractedSubBlock.gif        
fields
InBlock.gif
ContractedSubBlock.gif        
constructors
InBlock.gif
ContractedSubBlock.gif        
properties
InBlock.gif
ContractedSubBlock.gif        
methors
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

  在每次操作Student對象時,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果沒寫這一行運行時會出現“could not find class:NativePlace”(我就在寫卡了好久)

類NativePlace的代碼如下:
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
None.gif
namespace NHibernateTest
ExpandedBlockStart.gif
{
InBlock.gif    
public class NativePlace : BizObject
ExpandedSubBlockStart.gif    
{
ContractedSubBlock.gif        
fields
InBlock.gif
ContractedSubBlock.gif        
properties
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,1constraint PK_UserID1 Primary Key,
None.gif  
[UserName] varchar(20not null,
None.gif  
[Password] varchar(20not 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.gifusing 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.gif
{
InBlock.gif    
public partial class frmStudent : Form
ExpandedSubBlockStart.gif    
{
InBlock.gif        
public frmStudent()
ExpandedSubBlockStart.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.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.gif            
{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.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.gif        
{
InBlock.gif            objStudent.UserName 
= "Update UserName";
InBlock.gif            objStudent.NativePlace.Province 
= "Update Province";
InBlock.gif
InBlock.gif            
if (objStudent.updateStudent())
ExpandedSubBlockStart.gif            
{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.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.gif        
{
InBlock.gif            
if (objStudent.deleteStudent())
ExpandedSubBlockStart.gif            
{
InBlock.gif                MessageBox.Show(
"Success");
ExpandedSubBlockEnd.gif            }

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

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

  所有的類和映射文件都寫好了,運行...成功.
發佈了70 篇原創文章 · 獲贊 5 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章