基于NHibernate的三層結(jié)構(gòu)應(yīng)用程序開(kāi)發(fā)初步Posted on 2006-02-16 17:46 Terrylee 閱讀(1731) 評(píng)論(16) 編輯 收藏 收藏至365Key 所屬分類(lèi): ORM本文并不是去詳細(xì)的介紹如何使用NHibernate,而是通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)演示基于NHibernate的三層結(jié)構(gòu)應(yīng)用程序開(kāi)發(fā)過(guò)程。關(guān)于NHibernate的有關(guān)文檔,DDL已經(jīng)做了漢化,但是由于英文文檔自身就不完善,所以漢化后也是不全。菩提樹(shù)在一篇《NHibernate學(xué)習(xí)之路》隨筆中談到了學(xué)習(xí)NHibernate遇到的困難,也希望大家把自己在使用NHibernate中的經(jīng)驗(yàn)和心得能夠共享出來(lái),與大家分享。另外我也是剛開(kāi)始接觸NHiernate,有錯(cuò)誤之處還請(qǐng)大家指點(diǎn)。 第一步:準(zhǔn)備數(shù)據(jù)表 在這里用一個(gè)最簡(jiǎn)單的例子,有一張關(guān)于的用戶(hù)的表,有編號(hào),姓名,密碼,Email地址和最后一次的登錄時(shí)間幾個(gè)字段。 Create Table Users(![]() LogonID varchar(20) Primary key,![]() Name varchar(40),![]() Password varchar(20),![]() EmailAddress varchar(40) ,![]() LastLogon datetime![]() )第二步:創(chuàng)建需要被持久化的類(lèi) 在.NET中創(chuàng)建一個(gè)NHibernateWebDemo.Model的工程,添加User實(shí)體類(lèi)。 //User.cs![]() using System;![]() namespace NHibernateWebDemo.Model![]() ![]() ![]() {![]() public class User![]() ![]() {![]() public User()![]() ![]() { ![]() }![]() private string id;![]() private string userName;![]() private string password;![]() private string emailAddress;![]() private DateTime lastLogon;![]() public string Id ![]() ![]() {![]() ![]() get { return id; }![]() ![]() set { id = value; }![]() }![]() public string UserName ![]() ![]() {![]() ![]() get { return userName; }![]() ![]() set { userName = value; }![]() }![]() public string Password ![]() ![]() {![]() ![]() get { return password; }![]() ![]() set { password = value; }![]() }![]() public string EmailAddress ![]() ![]() {![]() ![]() get { return emailAddress; }![]() ![]() set { emailAddress = value; }![]() }![]() public DateTime LastLogon ![]() ![]() {![]() ![]() get { return lastLogon; }![]() ![]() set { lastLogon = value; }![]() }![]() }![]() }第三步:創(chuàng)建持久化映射文件 該文件的命名為User.hbm.xml,并且與User.cs放在同一個(gè)目錄里。設(shè)置該文件的生成操作屬性為“嵌入的資源”,這一點(diǎn)要切記。另外,使用編號(hào)當(dāng)作主鍵,由用戶(hù)輸入,所以在映射文件中用assigned。 <?xml version="1.0" encoding="utf-8" ?>![]() <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">![]() <class name="NHibernateWebDemo.Model.User, NHibernateWebDemo.Model" table="users">![]() <id name="Id" column="LogonId" type="String" length="20"> ![]() <generator class="assigned" /> ![]() </id>![]() <property name="UserName" column= "Name" type="String" length="40"/> ![]() <property name="Password" type="String" length="20"/> ![]() <property name="EmailAddress" type="String" length="40"/>![]() <property name="LastLogon" type="DateTime"/>![]() </class>![]() </hibernate-mapping>第四步:進(jìn)行配置文件的設(shè)置 在配置文件中,我們要告訴NHibernate所使用的數(shù)據(jù)庫(kù)是什么,以及如何連接該數(shù)據(jù)庫(kù)。 <configSections>![]() <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />![]() </configSections>![]() <nhibernate>![]() <add key="hibernate.connection.provider" ![]() value="NHibernate.Connection.DriverConnectionProvider"/>![]() <add key="hibernate.dialect" ![]() value="NHibernate.Dialect.MsSql2000Dialect"/>![]() <add key="hibernate.connection.driver_class" ![]() value="NHibernate.Driver.SqlClientDriver"/>![]() <add key="hibernate.connection.connection_string" ![]() value="server=.;uid=sa;pwd=sa;database=test"/>![]() </nhibernate>第五步:編寫(xiě)數(shù)據(jù)訪問(wèn)層的公用類(lèi) 在這里,編寫(xiě)了兩個(gè)公用的類(lèi),分別進(jìn)行Session的創(chuàng)建和實(shí)體的操作。在這兩個(gè)類(lèi)中用單件模式,來(lái)限制Session的創(chuàng)建。為了做到與具體的應(yīng)用程序無(wú)關(guān),在這里把程序集的名稱(chēng)作為參數(shù),傳遞給OpenSession()方法??梢园堰@兩個(gè)類(lèi)單獨(dú)放在一個(gè)名為Common的工程下,這里先把它們放在DAL層中。這兩個(gè)類(lèi)只是個(gè)人的一種寫(xiě)法,大家可以自行去編寫(xiě)。 //SessionFactory.cs![]() using System;![]() using System.Reflection;![]() using System.Data;![]() using NHibernate;![]() using NHibernate.Cfg;![]() using NHibernate.Tool.hbm2ddl;![]() namespace NHibernateWebDemo.DAL![]() ![]() ![]() {![]() public class SessionFactory![]() ![]() {![]() public SessionFactory()![]() ![]() {![]() ![]() }![]() private static ISessionFactory sessions;![]() private static Configuration cfg;![]() static readonly object padlock = new object();![]() public static ISession OpenSession(string AssemblyName)![]() ![]() {![]() if(sessions == null)![]() ![]() {![]() lock(padlock)![]() ![]() {![]() if(sessions == null)![]() ![]() {![]() BuildSessionFactory(AssemblyName);![]() }![]() }![]() }![]() return sessions.OpenSession();![]() }![]() private static void BuildSessionFactory(string AssemblyName)![]() ![]() {![]() cfg = new Configuration();![]() cfg.AddAssembly(AssemblyName);![]() sessions = cfg.BuildSessionFactory();![]() }![]() }![]() }
//EntityControl.cs![]() using System;![]() using System.Collections;![]() using NHibernate;![]() ![]() namespace NHibernateWebDemo.DAL![]() ![]() ![]() {![]() public class EntityControl![]() ![]() {![]() private static EntityControl entity;![]() private string _AssemblyName;![]() static readonly object padlock = new object();![]() public static EntityControl CreateEntityControl(string AssemblyName)![]() ![]() {![]() if(entity == null)![]() ![]() {![]() lock(padlock)![]() ![]() {![]() if(entity == null)![]() ![]() {![]() entity = new EntityControl();![]() entity._AssemblyName = AssemblyName;![]() }![]() }![]() }![]() return entity;![]() }![]() public void AddEntity(Object entity)![]() ![]() {![]() ISession session = SessionFactory.OpenSession(_AssemblyName);![]() ITransaction transaction = session.BeginTransaction();![]() try![]() ![]() {![]() session.Save(entity);![]() transaction.Commit();![]() }![]() catch(Exception ex)![]() ![]() {![]() transaction.Rollback();![]() throw ex;![]() }![]() finally![]() ![]() {![]() session.Close();![]() }![]() }![]() public void UpdateEntity(Object entity,Object key)![]() ![]() {![]() ISession session = SessionFactory.OpenSession(_AssemblyName);![]() ITransaction transaction = session.BeginTransaction();![]() try![]() ![]() {![]() session.Update(entity,key);![]() transaction.Commit();![]() }![]() catch(Exception ex)![]() ![]() {![]() transaction.Rollback();![]() throw ex;![]() }![]() finally![]() ![]() {![]() session.Close();![]() }![]() }![]() public void DeleteEntity(object entity)![]() ![]() {![]() ISession session = SessionFactory.OpenSession(_AssemblyName);![]() ITransaction transaction = session.BeginTransaction();![]() try![]() ![]() {![]() session.Delete(entity);![]() transaction.Commit();![]() }![]() catch(Exception ex)![]() ![]() {![]() transaction.Rollback();![]() throw ex;![]() }![]() finally![]() ![]() {![]() session.Close();![]() }![]() }![]() public IList GetEntities(string strHQL)![]() ![]() {![]() IList lst;![]() ISession session = SessionFactory.OpenSession(_AssemblyName);![]() ITransaction transaction = session.BeginTransaction();![]() ![]() lst=session.Find(strHQL);![]() transaction.Commit();![]() session.Close();![]() return lst;![]() }![]() }![]() }第六步:編寫(xiě)數(shù)據(jù)訪問(wèn)層 創(chuàng)建一個(gè)名為NHibernateWebDemo.DAL的工程,數(shù)據(jù)訪問(wèn)層的代碼編寫(xiě)非常簡(jiǎn)單,在創(chuàng)建EntityControl的實(shí)例時(shí),需要把Model的程序集名稱(chēng)作為參數(shù)傳入,可以通過(guò)配置文件來(lái)避免程序集名稱(chēng)的硬編碼。 //UserDAL.cs![]() using System;![]() using System.Collections;![]() using NHibernateWebDemo.Model;![]() namespace NHibernateWebDemo.DAL![]() ![]() ![]() {![]() public class UserDAL![]() ![]() {![]() private EntityControl control;![]() public UserDAL()![]() ![]() {![]() control = EntityControl.CreateEntityControl("NHibernateWebDemo.Model");![]() }![]() public void AddUser(User user)![]() ![]() {![]() control.AddEntity(user);![]() }![]() public void UpdateUser(User user,string Id)![]() ![]() {![]() control.UpdateEntity(user,user.Id);![]() }![]() public void DeleteUser(User user)![]() ![]() {![]() control.DeleteEntity(user);![]() } ![]() public IList GetAllUsers(string strHQL)![]() ![]() {![]() return control.GetEntities(strHQL);![]() }![]() }![]() }第七步:編寫(xiě)業(yè)務(wù)邏輯層 建立NHibernateWebDemo.BLL工程,為了簡(jiǎn)單期間,在業(yè)務(wù)邏輯層中我沒(méi)有做任何的業(yè)務(wù)檢測(cè)。 //UserBLL.cs![]() using System;![]() using System.Collections;![]() using NHibernateWebDemo.DAL;![]() using NHibernateWebDemo.Model;![]() namespace NHibernateWebDemo.BLL![]() ![]() ![]() {![]() public class UserBLL![]() ![]() {![]() public void AddUser(User user)![]() ![]() { ![]() UserDAL dal = new UserDAL(); ![]() dal.AddUser(user);![]() }![]() public void UpdateUser(User user,string Id)![]() ![]() {![]() UserDAL dal = new UserDAL();![]() dal.UpdateUser(user,Id);![]() }![]() public void DeleletUser(User user)![]() ![]() {![]() UserDAL dal = new UserDAL();![]() dal.DeleteUser(user);![]() }![]() public IList GetAllUsers(string strHQL)![]() ![]() {![]() UserDAL dal = new UserDAL();![]() return dal.GetAllUsers(strHQL);![]() }![]() }![]() }第八步:實(shí)現(xiàn)用戶(hù)界面 用戶(hù)界面很簡(jiǎn)單,這里就不給出代碼了,完成后的用戶(hù)界面:
Feedback這個(gè),張老三寫(xiě)的那幾篇更好,而且他的DOMAINOBJECTCONTROL寫(xiě)的很棒
提幾個(gè)小建議: 1,業(yè)務(wù)邏輯層是不是該進(jìn)行一下業(yè)務(wù)邏輯的判斷呀 例如,ADD一個(gè)USER前,是不是該判斷是下該USER是不是存在 USER的各個(gè)屬性值,是否符合邏輯 這些都不做的話,這些工作放在哪兒呢? DAL僅負(fù)責(zé)串行化數(shù)據(jù)以及事務(wù)處理,而B(niǎo)AL剛負(fù)責(zé)業(yè)務(wù)邏輯,所謂業(yè)務(wù)邏輯,應(yīng)該包含這些吧 最后,一個(gè)建議,不要把校驗(yàn)的任務(wù)交給DBMS,不要依賴(lài)于它的約束等,雖然你寫(xiě)了約束等,但是,不要等在串行化時(shí),才檢查數(shù)據(jù)有效性 |
|
|
來(lái)自: liuqg > 《軟件設(shè)計(jì)》