1) 學習目標
通過進一步學習Nhibernate基礎知識,掌握用Nhiberate實現對級聯的支持,通過一個簡單的用戶角色權限系統來體驗nhibernate對級聯的強大支持。
?
2)開發環境和必要準備?
? 開發環境為:windows 2003,Visual studio .Net 2005,Sql server 2005 developer edition
? 必要準備:學習前三篇nhibernate學習系列
Nhibernate學習之起步篇-1? ,
Nhibernate學習起步之many-to-one篇 ,
Nhibernate學習之many-to-many篇 3)示例
? 業務需求:實現一個用戶角色權限系統,一個用戶只有一個角色,一個角色下有多個用戶,一個角色下有多個權限,一個權限也對應多個角色
????????????????????? 要求: (1).創建一個角色 (2)在該角色上創建兩個個用戶3)創建兩個權限4)指定該角色上的權限列表5)獲得一個用戶的權限列表
? 首先看關系數據庫關系圖:
??

4)實現步驟:
? 1.User.cs
using?System;
using?System.Collections.Generic;
using?System.Text;

namespace?NhibernateSample1


{
????public?class?User

????
{
????????private?int?_id;
????????private?string?_name;
????????private?string?_pwd;
????????private?Role?_role;

????????/**////?<summary>
????????///?編號
????????///?</summary>
????????public?virtual?int?Id

????????
{
????????????get

????????????
{
????????????????return?_id;
????????????}
????????????set

????????????
{
????????????????_id?=?value;
????????????}
????????}


????????/**////?<summary>
????????///?名稱
????????///?</summary>
????????public?virtual?string?Name

????????
{
????????????get

????????????
{
????????????????return?_name;
????????????}
????????????set

????????????
{
????????????????_name?=?value;
????????????}
????????}


????????/**////?<summary>
????????///?密碼
????????///?</summary>
????????public?virtual?string?Pwd

????????
{
????????????get

????????????
{
????????????????return?_pwd;
????????????}
????????????set

????????????
{
????????????????_pwd?=?value;
????????????}
????????}
????????public?virtual?Role?Role

????????
{
????????????get

????????????
{
????????????????return?_role;
????????????}
????????????set

????????????
{
????????????????_role?=?value;
????????????}
????????}
????}
}

?User.hbm.xml
<?xml?version="1.0"?encoding="utf-8"??>
<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.2">
??<class?name="NhibernateSample1.User,NhibernateSample1"?table="Users"?lazy="false">
????<id?name="Id"?column="Id"?unsaved-value="0">
??????<generator?class="native"?/>
????</id>
????<property?name="Name"?column="Name"?type="string"?length="64"?not-null="true"?unique="true"></property>
????<property?name="Pwd"??column="Pwd"??type="string"?length="64"?not-null="true"></property>
????<many-to-one?name="Role"??class="NhibernateSample1.Role,NhibernateSample1"?column="RoleID"></many-to-one>
???</class>
</hibernate-mapping> 2.Role.cs
using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Collections;

namespace?NhibernateSample1


{
????public?class?Role

????
{
????????int?_roleID;
????????string?_roleName;
????????IList?_list?=?new??ArrayList();
????????IList?_permissionList?=?new?ArrayList();
????????public?virtual?IList?PermissionList

????????
{
????????????get

????????????
{
????????????????return?_permissionList;
????????????}
????????????set

????????????
{
????????????????_permissionList?=?value;
????????????}
????????}
????????public?virtual?int?RoleID

????????
{
????????????get

????????????
{
????????????????return?_roleID;
????????????}
????????????set

????????????
{
????????????????_roleID?=?value;
????????????}
????????}
????????public?virtual?IList?UserList

????????
{
????????????get

????????????
{
????????????????return?_list;
????????????}
????????????set

????????????
{
????????????????_list?=?value;
????????????}
????????}
????????public?virtual?string?RoleName

????????
{
????????????get

????????????
{
????????????????return?_roleName;
????????????}
????????????set

????????????
{
????????????????_roleName?=?value;
????????????}
????????}
????}
}

Role.hbm.xml
<?xml?version="1.0"?encoding="utf-8"??>
<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.2">
??<class?name="NhibernateSample1.Role,NhibernateSample1"?table="Roles"?lazy="false">
????<id?name="RoleID"?column="RoleID"?unsaved-value="0">
??????<generator?class="native"?/>
????</id>
????<property?name="RoleName"??column="RoleName"??type="string"?length="64"?not-null="true"></property>
????<bag?name="PermissionList"?table="Role_Permissions"?inverse="true"?lazy="false"?cascade="all">
??????<key?column="RoleID"/>
??????<many-to-many?class="NhibernateSample1.Permission,NhibernateSample1"?column="PermissionID"></many-to-many>
????</bag>
????<bag?name="UserList"?table="Users"?inverse="true"?lazy="false"?cascade="all">
??????<key?column="RoleID"/>
??????<one-to-many?class="NhibernateSample1.User,NhibernateSample1"></one-to-many>
????</bag>
??</class>
</hibernate-mapping> 3.Permission.cs
using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Collections;

namespace?NhibernateSample1


{
????public?class?Permission

????
{
????????int?_permissionID;
????????string?_permissionName;
????????IList?_roleList?=?new?ArrayList();
????????public?virtual?int?PermissionID

????????
{
????????????get

????????????
{
????????????????return?_permissionID;
????????????}
????????????set

????????????
{
????????????????_permissionID?=?value;
????????????}
????????}
????????public?virtual?string?PermissionName

????????
{
????????????get

????????????
{
????????????????return?_permissionName;
????????????}
????????????set

????????????
{
????????????????_permissionName=value;
????????????}
????????}
????????public?virtual?IList?RoleList

????????
{
????????????get

????????????
{
????????????????return?_roleList;
????????????}
????????????set

????????????
{
????????????????_roleList?=?value;
????????????}
????????}
????}
}

Permission.hbm.xml
<?xml?version="1.0"?encoding="utf-8"??>
<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.2">
??<class?name="NhibernateSample1.Permission,NhibernateSample1"?table="Permissions"?lazy="false">
????<id?name="PermissionID"?column="PermissionID"?unsaved-value="0">
??????<generator?class="native"?/>
????</id>
????<property?name="PermissionName"?column="PermissionName"?type="string"?length="64"?not-null="true"?unique="true"></property>
????<bag?name="RoleList"?table="Role_Permissions"??lazy="true">
??????<key?column="PermissionID"/>
??????<many-to-many?class="NhibernateSample1.Role,NhibernateSample1"?column="RoleID"></many-to-many>
????</bag>
??</class>
</hibernate-mapping> 4。數據操作類

UserRolePermissionFixure
using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Collections;
using?NHibernate;
using?NHibernate.Cfg;
using?NHibernate.Tool.hbm2ddl;

namespace?NhibernateSample1


{
????public??class?UserRolePermissionFixure

????
{
????????private?ISessionFactory?_sessions;?
????????public?void?Configure()

????????
{
????????????Configuration?cfg?=?GetConfiguration();??????
????????????_sessions?=?cfg.BuildSessionFactory();
????????}
????????Configuration?GetConfiguration()

????????
{
????????????string?cfgPath?=?@"E:\my?project\nhibernate?study\simle?1\NHibernateStudy1\NhibernateSample1\hibernate.cfg.xml";
????????????Configuration?cfg?=?new?Configuration().Configure(cfgPath);
????????????return?cfg;
????????}
????????public?void?ExportTables()

????????
{
????????????Configuration?cfg?=?GetConfiguration();???????????
????????????new?SchemaExport(cfg).Create(true,?true);
????????}
????????public?Role?CreateRole(string?roleName)

????????
{
????????????Role?r?=?new?Role();
????????????r.RoleName?=?roleName;
????????????ISession?session?=?_sessions.OpenSession();????????????
????????????ITransaction?tx?=?null;
????????????try

????????????
{
????????????????tx?=?session.BeginTransaction();
????????????????session.Save(r);
????????????????tx.Commit();
????????????}
????????????catch(Exception?e)

????????????
{
????????????????if?(tx?!=?null)?tx.Rollback();
????????????????throw?e;
????????????}
????????????finally

????????????
{
????????????????session.Close();
????????????}
????????????return?r;

????????}

????????public?User?CreateUser(String?name,string?pwd,Role?r)

????????
{
????????????User?u?=?new?User();
????????????u.Name?=?name;
????????????u.Pwd?=?pwd;
????????????u.Role?=?r;
????????????//r.UserList.Add(u);
????????????ISession?session?=?_sessions.OpenSession();

????????????ITransaction?tx?=?null;

????????????try

????????????
{
????????????????tx?=?session.BeginTransaction();
????????????????session.Save(u);
????????????????tx.Commit();
????????????}
????????????catch?(HibernateException?e)

????????????
{
????????????????if?(tx?!=?null)?tx.Rollback();
????????????????throw?e;
????????????}
????????????finally

????????????
{
????????????????session.Close();
????????????}

????????????return?u;
????????}
????????public?Permission?CreatePermission(Role?r,string?name)

????????
{
????????????Permission?p?=?new?Permission();
????????????p.PermissionName?=?name;
????????????r.PermissionList.Add(p);
????????????p.RoleList.Add(r);
????????????ISession?session?=?_sessions.OpenSession();
????????????ITransaction?tx?=?null;

????????????try

????????????
{
????????????????tx?=?session.BeginTransaction();
????????????????session.Save(p);
????????????????tx.Commit();
????????????}
????????????catch?(HibernateException?e)

????????????
{
????????????????if?(tx?!=?null)?tx.Rollback();
????????????????throw?e;
????????????}
????????????finally

????????????
{
????????????????session.Close();
????????????}
????????????return?p;
????????}
????????public?void?DeleteRole(int?rid)

????????
{
????????????ISession?session?=?_sessions.OpenSession();
????????????ITransaction?tx?=?null;
????????????try

????????????
{
????????????????tx?=?session.BeginTransaction();
????????????????Role?item?=?session.Load(typeof(Role),?rid)?as?Role;
????????????????session.Delete(item);
????????????????tx.Commit();
????????????}
????????????catch?(HibernateException?e)

????????????
{
????????????????if?(tx?!=?null)?tx.Rollback();
????????????????throw?e;
????????????}
????????????finally

????????????
{
????????????????session.Close();
????????????}
????????}

????}
}

5。單元測試類

UnitTest1.cs
using?System;
using?System.Text;
using?System.Collections.Generic;
using?Microsoft.VisualStudio.TestTools.UnitTesting;
using?NhibernateSample1;

namespace?TestProject1


{

????/**////?<summary>
????///?UnitTest1?的摘要說明
????///?</summary>
????[TestClass]
????public?class?UnitTest1

????
{
????????public?UnitTest1()

????????
{
????????????//
????????????//?TODO:?在此處添加構造函數邏輯
????????????//
????????}
????????NhibernateSample1.UserRolePermissionFixure?usf?=?new?UserRolePermissionFixure();

????????其他測試屬性#region?其他測試屬性
????????//
????????//?您可以在編寫測試時使用下列其他屬性:
????????//
????????//?在運行類中的第一個測試之前使用?ClassInitialize?運行代碼
????????//?[ClassInitialize()]
????????//?public?static?void?MyClassInitialize(TestContext?testContext)?{?}
????????//
????????//?在類中的所有測試都已運行之后使用?ClassCleanup?運行代碼
????????//?[ClassCleanup()]
????????//?public?static?void?MyClassCleanup()?{?}
????????//
????????//?在運行每個測試之前使用?TestInitialize?運行代碼?
????????//?[TestInitialize()]
????????//?public?void?MyTestInitialize()?{?}
????????//
????????//?在運行每個測試之后使用?TestCleanup?運行代碼
????????//?[TestCleanup()]
????????//?public?void?MyTestCleanup()?{?}
????????//
????????#endregion

????????[TestMethod]
????????public?void?Test1()

????????
{
????????????usf.Configure();
????????????usf.ExportTables();
????????????Role?r?=?usf.CreateRole("test");
????????????Assert.IsTrue(r.RoleID?>?0);
????????????User?u?=?usf.CreateUser(Guid.NewGuid().ToString(),?"ds",?r);????????????
????????????Assert.IsTrue(u.Id?>?0);
????????????Permission?p?=?usf.CreatePermission(r,?"查詢");
????????????Assert.IsTrue(p.PermissionID?>?0);?????????
????????}

????}
}

?? 通過本篇的學習,將充分理解到nhibernate對級聯支持的強大。另外除了支持三級聯之外,他還支持異類關聯(Heterogeneous Associations) .給開發帶來了更多的靈活性和實用性。而且考慮到性能的問題,還添加了lazy這樣的延遲加載的功能,加載父親不必要一定要加載他的兒子集合。通過集合類映射,nhinernate輕松實現級聯,這相比較代碼生成來說,無疑是一個優點。?