1.
学习目的 :
通过进一步学习nhibernate基础知识,在实现单表CRUD的基础上,实现两表之间one-to-many的关系.
2. 开发环境+必要准备
开发环境: windows 2003,Visual studio .Net 2005,Sql server 2005 developer edition
必要准备: 学习上篇文章单表操作
3) 更改User.cs,在User里面添加SalaryList属性: 4)修改User.hbm.xml ,加入bag 节点5)编写类Salary的映射文件:Salary.hbm.xml
Salary.hbm.xml
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><? xmlversion = " 1.0 " encoding = " utf-8 " ?> < hibernate - mappingxmlns = " urn:nhibernate-mapping-2.2 " > < class name = " NhibernateSample1.Salary,NhibernateSample1 " table = " Salary " lazy = " false " > < idname = " Id " column = " Id " unsaved - value = " 0 " > < generator class = " native " /> </ id > < propertyname = " Year " column = " Year " type = " Int32 " not - null = " true " ></ property > < propertyname = " Month " column = " Month " type = " Int32 " not - null = " true " ></ property > < propertyname = " Envy " column = " Envy " type = " Int32 " not - null = " true " ></ property > < propertyname = " Money " column = " Money " type = " Decimal " not - null = " true " ></ property > < many - to - onename = " Employee " column = " Uid " not - null = " true " ></ many - to - one > </ class > </ hibernate - mapping >
6
)编写
CRUD 类
UserSalaryFixure.cs
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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 UserSalaryFixure { private ISessionFactory_sessions; public void Configure() { Configurationcfg = GetConfiguration(); _sessions = cfg.BuildSessionFactory(); } ConfigurationGetConfiguration(){ string cfgPath = @" E:/myproject/nhibernatestudy/simle1/NHibernateStudy1/NhibernateSample1/hibernate.cfg.xml " ; Configurationcfg = new Configuration().Configure(cfgPath); return cfg; } public void ExportTables() { Configurationcfg = GetConfiguration(); new SchemaExport(cfg).Create( true , true ); } public UserCreateUser(Stringname, string pwd) { Useru = new User(); u.Name = name; u.Pwd = pwd; u.SalaryList = new ArrayList(); ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); session.Save(u); tx.Commit(); } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); throw e; } finally { session.Close(); } return u; } public SalaryCreateSalary(Useru, int year, int month, int envy, decimal money) { Salaryitem = new Salary(); item.Year = year; item.Money = money; item.Envy = envy; item.Month = month; item.Employee = u; u.SalaryList.Add(item); ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); session.Update(u); tx.Commit(); } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); throw e; } finally { session.Close(); } return item; } public SalaryCreateSalary( int uid, int year, int month, int envy, decimal money) { Salaryitem = new Salary(); item.Year = year; item.Money = money; item.Envy = envy; item.Month = month; ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); Useru = (User)session.Load( typeof (User),uid); item.Employee = u; u.SalaryList.Add(item); tx.Commit(); } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); throw e; } finally { session.Close(); } return item; } public SalaryGetSalary( int salaryID) { ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); Salaryitem = (Salary)session.Load( typeof (Salary), salaryID); tx.Commit(); return item; } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); return null ; } finally { session.Close(); } return null ; } public UserGetUser( int uid) { ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); Useritem = (User)session.Load( typeof (User), uid); tx.Commit(); return item; } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); return null ; } finally { session.Close(); } return null ; } public void UpdateSalary( int salaryID, decimal money) { ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); Salaryitem = (Salary)session.Load( typeof (Salary), salaryID); item.Money = money; tx.Commit(); } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); throw e; } finally { session.Close(); } }public void Delete( int uid) { ISessionsession = _sessions.OpenSession(); ITransactiontx = null ; try { tx = session.BeginTransaction(); Salaryitem = session.Load( typeof (Salary),uid) as Salary;; session.Delete(item); tx.Commit(); } catch (HibernateExceptione) { if (tx != null )tx.Rollback(); throw e; } finally { session.Close(); } } } }
7)
编写单元测试类:
UnitTest1.cs
UnitTest1.cs
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->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.UserSalaryFixureusf= new UserSalaryFixure(); 其他测试属性 #region 其他测试属性 // // 您可以在编写测试时使用下列其他属性: // // 在运行类中的第一个测试之前使用ClassInitialize运行代码 // [ClassInitialize()] // publicstaticvoidMyClassInitialize(TestContexttestContext){} // // 在类中的所有测试都已运行之后使用ClassCleanup运行代码 // [ClassCleanup()] // publicstaticvoidMyClassCleanup(){} // // 在运行每个测试之前使用TestInitialize运行代码 // [TestInitialize()] // publicvoidMyTestInitialize(){} // // 在运行每个测试之后使用TestCleanup运行代码 // [TestCleanup()] // publicvoidMyTestCleanup(){} // #endregion [TestMethod]public void Test1() { usf.Configure(); usf.ExportTables(); Useru = usf.CreateUser(Guid.NewGuid().ToString(), " ds " ); Assert.IsTrue(u.Id > 0 ); Salarys = usf.CreateSalary(u, 2007 , 3 , 1 ,( decimal ) 8000.00 ); Assert.IsTrue(s.Id > 0 ); Salarys1 = usf.CreateSalary(u.Id, 2007 , 3 , 1 ,( decimal ) 7500 ); Assert.IsTrue(s1.Id > 0 ); usf.UpdateSalary(s1.Id,( decimal ) 6000 ); s1 = usf.GetSalary(s1.Id); Assert.IsTrue(s1.Money == ( decimal ) 6000 ); usf.Delete(s1.Id); s1 = usf.GetSalary(s1.Id); Assert.IsNull(s1); Useru1 = usf.GetUser( 1 ); Assert.IsTrue(u1.SalaryList.Count > 0 ); } } }
加载测试元数据,直到Test()通过。
总结:通过进一步学习nhiberate,发现ORM框架真是非常强大。今天先到这里。明天继续。 项目文件:
/Files/jillzhang/simple2.rar
User.cs
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->1 private System.Collections.IList_salaryList; 2 /**/ /// <summary> 3 /// 工资列表 4 /// </summary> 5 public System.Collections.IListSalaryList 6 { 7 get 8 { 9 return _salaryList; 10 }11 set 12 { 13 _salaryList= value; 14 }15 }
3. 对上篇文章中部分解释
1)在User.hbm.xml中class节点中有一个lazy的属性,这个属性用于指定是否需要延迟加载(lazy loading),在官方文档中称为:lazy fecting.可以说延迟加载是nhibernate最好的特点,因为它可以在父类中透明的加载子类集合,这对于many-to-one的业务逻辑中,真是方便极了。但是有些时候,父类是不需要携带子类信息的。这时候如果也加载,无疑对性能是一种损失。在映射文件的class节点中可以通过配置lazy属性来指定是否支持延迟加载,这就更灵活多了。
2) 在User.hbm.xml中generate节点,代表的是主键的生成方式,上个例子中的”native”根据底层数据库的能力选择identity,hilo,sequence中的一个,比如在MS Sql中,使我们最经常使用的自动增长字段,每次加1.
3) 在NHibernateHelper.cs中,创建Configuration对象的代码:new Configuration().Configure(@"E:/myproject/nhibernatestudy/simle1/NHibernateStudy1/NhibernateSample1/hibernate.cfg.xml");因为我是在单元测试中调试,所以将绝对路径的配置文件传递给构造函数。如果在windows app或者web app可以不用传递该参数。
4. 实现步骤
1)确定实现的业务需求:用户工资管理系统
2) 打开上篇文章中的NHibernateStudy1解决方案。向项目NhibernateSample1添加类Salary;代码如下
Salary.cs
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->using System; using System.Collections.Generic; using System.Text; namespace NhibernateSample1 { public partial class Salary { int _id; User_user; int _year; int _month; int _envy; decimal _money; /**/ /// <summary> /// 工资编号 /// </summary> public virtual int Id { get { return _id; } set { _id = value; } }/**/ /// <summary> /// 雇员 /// </summary> public virtual UserEmployee { get { return _user; } set { _user = value; } }/**/ /// <summary> /// 年度 /// </summary> public int Year { get { return _year; } set { _year = value; } }/**/ /// <summary> /// 月份 /// </summary> public int Month { get { return _month; } set { _month = value; } }/**/ /// <summary> /// 季度 /// </summary> public int Envy { get { return _envy; } set { _envy = value; } }/**/ /// <summary> /// 工资 /// </summary> public decimal Money { get { return _money; } set { _money = value; } } } }
User.hbm.xml
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->< bagname = " SalaryList " table = " Salary " inverse = " true " lazy = " true " cascade = " all " > < keycolumn = " Id " /> < one - to - many class = " NhibernateSample1.Salary,NhibernateSample1 " ></ one - to - many > </ bag >