1.介紹NH如何處理對象間one-to-ont的映射關係;
經驗教訓:
1.操作一對一關聯關係中的一個對象時,得在程序中指定如何與另一個對象關聯,如在Student類中寫this.NativePlace.Student = this;
2.在爲類寫映射文件時,必須指定類的具體的名稱空間,若則運行時會出現"找不到***映射文件"的問題;
這兩點都困擾了我好長一段時間,應該要引起注意.
點擊下載本文相關代碼(可在上篇代碼的基礎上做修改)
one-to-one:
NH中處理一對一關聯的方式有兩種:
1.主鍵關聯
2.惟一外鍵關聯
本文使用主鍵關聯處理一對一的關係。
主鍵關聯不需要額外的表字段;兩行是通過這種一對一關係相關聯的,那麼這兩行就共享同樣的主關鍵字值。所以如果你希望兩個對象通過主鍵一對一關聯,你必須確認它們被賦予同樣的標識值!
持久化對象之間一對一的關聯關係是通過one
-to-one
元素定義的。
name="propertyName"(1)
class="ClassName"(2)
cascade="all|none|save-update|delete"(3)
constrained="true|false"(4)
outer-join="true|false|auto"(5)
property-ref="propertyNameFromAssociatedClass" (6)
access="field|property|ClassName"(7)
/>
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.Collections.Generic;
using System.Text;
namespace NHibernateTest
{
public class Student : User
{
fields
constructors
properties
methors
}
}
在每次操作Student對象時,都得指定NativePlace.Student,如:this.NativePlace.Student = this;如果沒寫這一行運行時會出現“could not find class:NativePlace”(我就在寫卡了好久)
類NativePlace的代碼如下:
using System.Collections.Generic;
using System.Text;
namespace NHibernateTest
{
public class NativePlace : BizObject
{
fields
properties
}
}
這兩個類的定義相對於User類沒有什麼太大的區別,接下來介紹兩個類的配置文件。
從UML來看,類NativePlace與類User之間是集合(構成)關係,即類NativePlace屬於類Student的一部分,但不能獨立存在,也就是說類NativePlace是依賴於類User的。
數據庫腳本:
Create Table [Users]
(
[ID] int identity(1,1) constraint PK_UserID1 Primary Key,
[UserName] varchar(20) not null,
[Password] varchar(20) not null
)
--表NativePlace:用於保存NativePlace對象
Create Table NativePlace
(
--表NativePlace與表Users通過主鍵關聯,則需保證兩表的主鍵名一致
ID int Constraint PK_NativePlaceID Primary Key,
Province varchar(50),
City varchar(50)
)
類Student的映射文件:
<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"/>
<one-to-one name="NativePlace" class="NHibernateTest.NativePlace,NHibernateTest" cascade="all" />
</class>
</hibernate-mapping>
類NativePlace的映射文件:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="NHibernateTest.NativePlace,NHibernateTest" table="NativePlace">
<id name="NPID" column="ID" type="Int32" unsaved-value="0">
<generator class="foreign">
<param name="property">Student</param>
</generator>
</id>
<property name="Province" column="Province" 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>
</class>
</hibernate-mapping>
接下來是測試類:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace NHibernateTest
{
public partial class frmStudent : Form
{
public frmStudent()
{
InitializeComponent();
}
Student objStudent;
//Add New Student
private void button1_Click(object sender, EventArgs e)
{
objStudent = new Student();
objStudent.UserName = "jailu";
objStudent.Password = "123";
objStudent.NativePlace.Province = "FuJian";
objStudent.NativePlace.City = "LongYan";
if (objStudent.addNewStudent())
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("UnSuccess");
}
}
//Update
private void btnUpdate_Click(object sender, EventArgs e)
{
objStudent.UserName = "Update UserName";
objStudent.NativePlace.Province = "Update Province";
if (objStudent.updateStudent())
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("UnSuccess");
}
}
//Delete
private void btnDelete_Click(object sender, EventArgs e)
{
if (objStudent.deleteStudent())
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("UnSuccess");
}
}
}
}
所有的類和映射文件都寫好了,運行...成功.