- 學習目的:
通過進一步學習Nhibernate基礎知識,掌握用Nhiberate實現多對多的業務邏輯
- 開發環境+必要準備
開發環境: windows 2003,Visual studio .Net 2005,Sql server 2005 developer edition
前期準備: 學習上兩篇單表操作和many-to-one篇
3.對上篇文章的部分解釋
1)bag節點:用于定義System.Collection.IList類型的集合元素。
|
屬性
|
用法
|
舉例
|
|
name
|
映射的屬性(必須)
|
name=”SalaryList”
|
|
table
|
映射的數據表(可選) |
table=”Salary” |
| lazy |
延遲加載(可選) |
Lazy=true|false |
| cascade |
指示級聯操作方式(可選) |
Cascade=all |
| inverse |
關聯由誰負責維護 |
Inverse=”true” |
當lazy=”true”,父類初始化的時候不會自動加載子類集合
Cascade為級聯操作方式,包括:
| 屬性 |
用法說明 |
| none |
默認值,不進行級聯操作 |
| save-update |
save和update級聯 |
| delete |
刪除級聯 |
| delete-orphan |
刪除不相關的父對象的子對象 |
| all |
save/update/delete級聯 |
| all-delete-orphan |
all+delete-arphan |
當inverse=”true”的時候代表由子類維護級聯關系。這時候如果只往父類中添加子類,但不設定子類的父類,是不能保存子類的。
4.多對多業務模型
還是用戶系統,1個用戶職員隸屬于多個部門,同時1個部門有多個不同的職員
用戶和部門之間的數據關系圖為:

5. 實現步驟:
1)User.cs

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 System.Collections.IList _departmentsList;

/**//// <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;
}
}

/**//// <summary>
/// 工資列表
/// </summary>
public System.Collections.IList DepartmentsList

{
get

{
return _departmentsList;
}
set

{
_departmentsList = value;
}
}
}
}

2)User.hbm.xml

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>
<bag name="DepartmentsList" table="Users_Departments" inverse="true" lazy="false" cascade="all">
<key column="Id"/>
<many-to-many class="NhibernateSample1.Departments,NhibernateSample1" column="DepID"></many-to-many>
</bag>
</class>
</hibernate-mapping>
3) Departments.cs

Departments
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace NhibernateSample1


{
public class Departments

{
int _depID;
string _name;
IList _usersList= new ArrayList();
public virtual int DepID

{
get

{
return _depID;
}
set

{
_depID = value;
}
}
public virtual string Name

{
get

{
return _name;
}
set

{
_name = value;
}
}
public virtual IList UsersList

{
get

{
return _usersList;
}
set

{
_usersList = value;
}
}
}
}

4) Departments.hbm.xml

Departments.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="NhibernateSample1.Departments,NhibernateSample1" table="Departments" lazy="false">
<id name="DepID" column="DepID" unsaved-value="0">
<generator class="native" />
</id>
<property name="Name" column="Name" type="string" length="64" not-null="true" unique="true"></property>
<bag name="UsersList" table="Users_Departments" lazy="true" >
<key column="DepID"/>
<many-to-many class="NhibernateSample1.User,NhibernateSample1" column="Id"></many-to-many>
</bag>
</class>
</hibernate-mapping>
5) 數據操作類

UserDepartmentFixure.cs
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 UserDepartmentFixure

{
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 User CreateUser(String name,string pwd)

{
User u = new User();
u.Name = name;
u.Pwd = pwd;
u.DepartmentsList = new ArrayList();

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 Departments CreateDepartments(User u, string name)

{
Departments item = new Departments();
item.Name=name;
u.DepartmentsList.Add(item);
item.UsersList.Add(u);
ISession session = _sessions.OpenSession();
ITransaction tx = null;

try

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

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

{
session.Close();
}
return item;
}
public Departments GetDepartments(int depID)

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

{
tx = session.BeginTransaction();
Departments item = (Departments)session.Load(typeof(Departments),
depID);
tx.Commit();
return item;
}
catch (HibernateException e)

{
if (tx != null) tx.Rollback();
return null;
}
finally

{
session.Close();
}
return null;
}
public User GetUser(int uid)

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

{
tx = session.BeginTransaction();
User item = (User)session.Load(typeof(User),
uid);
tx.Commit();
return item;
}
catch (HibernateException e)

{
if (tx != null) tx.Rollback();
return null;
}
finally

{
session.Close();
}
return null;
}

public void Delete(int uid)

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

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

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

{
session.Close();
}
}

}
}

6)單元測試類

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.UserDepartmentFixure usf = new UserDepartmentFixure();

其他測試屬性#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();
User u = usf.CreateUser(Guid.NewGuid().ToString(), "ds");
Assert.IsTrue(u.Id>0);
Departments s = usf.CreateDepartments(u, "政治部");
Assert.IsTrue(s.DepID > 0);
Departments s1 = usf.CreateDepartments(u, "事業部");
Assert.IsTrue(s1.DepID > 0);
usf.Delete(s1.DepID);
s1 = usf.GetDepartments(s1.DepID);
Assert.IsNull(s1);
User u1 = usf.GetUser(1);
Assert.IsTrue(u1.DepartmentsList.Count>0);
}

}
}

到現在為止,終于更加體會到nhibernate的強大了。繼續努力,fight!
files:
/Files/jillzhang/simple3.rar 上幾篇文章:
Nhibernate學習之起步篇-1 Nhibernate分析之華山論劍篇 Nhibernate學習起步之many-to-one篇