NHibernate初學體驗進階篇

在上篇NHibernate初學體檢記》中,我參照NHibernate官方快速指南寫了兩個示例項目,在示例2的源碼中充斥了如下類似的代碼:<?XML:NAMESPACE PREFIX = O />

??????????? Configuration cfg = new Configuration();

??????????? cfg.AddAssembly("NHibernate.Examples");

??????????? ISessionFactory factory = cfg.BuildSessionFactory();

??????????? ISession session = factory.OpenSession();

??????????? ITransaction transaction = session.BeginTransaction();

?

如何解決這個問題呢?答案就是采用DAOData Access Object)模式。

?

一、編寫DAO

DAO其實就是把對實體的基本CRUD(創建、讀取、更新、刪除)操作進行封裝。在本示例中也就是把對User實體的持久化操作進行封裝,看下代碼就什么都清楚了(相比以前的簡單代碼,我又加入了異常處理部分J):

public class UserDAO

??? {

??????? private ISession session;

??????? private ITransaction tx;

?

??????? public void Create(User newUser)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Save(newUser);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

??????? }

?

??????? public void Update(User newUser)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Update(newUser);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

??????? }

?

??????? public void Delete(User user)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Delete(user);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

????? ??????finally

??????????? {

??????????????? session.Close();

??????????? }

??????? }

?

??????? public User Find(string id)

??????? {

??????????? User user = null;

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

??????????? {

??????????????? StartOperation();

??????????????? user = session.Get<User>(id);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

?

??????????? return user;

??????? }

?

??????? public IList FindAll()

??????? {

??????????? IList userList = null;

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

??????????? {

??????????????? StartOperation();

??????????????? userList = session.CreateCriteria(typeof(User)).List();

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

??????????? return userList;

??????? }

?

??????? //---------------------------------------------------

??????? private void StartOperation()

??????? {

??????????? Configuration cfg = new Configuration();

??????????? cfg.AddAssembly("NHibernate. Examples");

?

??????????? ISessionFactory factory = cfg.BuildSessionFactory();

?

??????????? session = factory.OpenSession();

??????????? tx = session.BeginTransaction();

??????? }

?

??????? private void HandleException(HibernateException e)

??????? {

??????????? tx.Rollback();

????????? ??throw e;

??????????? //注:你可以在此寫自己的異常處理,如記錄日志...

??????? }

??? }

?

有了UserDAO我們對User實體的操作簡化為簡單的兩行代碼(如下添加用戶的示例):

User newUser = new User();

??????????? newUser.Id = txtLogonID.Text.Trim();

??????????? newUser.UserName = txtName.Text.Trim();

??????????? newUser.Password = txtPassword.Text.Trim();

??????????? newUser.EmailAddress = txtEmailAddress.Text.Trim();

??????????? newUser.LastLogon = DateTime.Now;

??????????? //----------------------------------------------------

??????????? UserDAO userDAO = new UserDAO();

??????????? userDAO.Create(newUser);

?

NHibernate的那些充斥期間的初始化和收尾代碼不見了,DAO模式明顯降低了應用程序與NHibernate的耦合度。看起來不錯J,不過,這里有潛在的重復問題:我們的示例比較簡單,只有一個User實體類,正常的項目中會有大量這樣的的實體類,也就會有大量對應的DAO類,我們的“復制/粘貼”惡夢開始了,你要為所有的DAO類編寫類似于UserDAO類的代碼,這里面明顯有很多的重復,我們再寫其它的DAO類時,需要改變的僅僅是實體類,其余代碼都是“復制/粘貼”來的。“復制/粘貼”----所有編程問題的根源!(摘自《Hibernate Quickly中文版》P149)。這時候我們就需要“抽象”了!(突然覺得“抽象”是不是“抽出那些相象的部分”之意,哈哈!)

?

二、抽象DAO

我們來創建一個抽象的DAOAbstractDAO,作為超類,讓其它的DAO繼承之。AbstractDAO封裝那些“相象”的部分,以簡化實體DAO的編寫。看代碼吧:

public abstract class AbstractDAO

??? {

??????? private ISession session;

??????? private ITransaction tx;

?

??????? protected void Save(Object obj)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Save(obj);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

????? ??????}

??????? }

?

??????? protected void Update(Object obj)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Update(obj);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

??????? }

?

??????? protected void Delete(Object obj)

??????? {

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

??????????? {

??????????????? StartOperation();

??????????????? session.Delete(obj);

??????????????? tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

??????? }

?

??????? protected Object Find(System.Type clazz, Object id)

??????? {

??????????? Object obj = null;

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

??????????? {

??????????????? StartOperation();

??????????????? obj = session.Get(clazz,id);

???????? ???????tx.Commit();

??????????? }

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

?

??????????? return obj;

??????? }

?

??????? protected IList FindAll(System.Type clazz)

??????? {

??????????? IList objList = null;

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

??????????? {

??????????????? StartOperation();

??????????????? objList = session.CreateCriteria(clazz).List();

??????????????? tx.Commit();

??? ????????}

??????????? catch (HibernateException e)

??????????? {

??????????????? HandleException(e);

??????????? }

??????????? finally

??????????? {

??????????????? session.Close();

??????????? }

?

??????????? return objList;

??????? }???????

?

???????

?

??????? //---------------------------------------------------

??????? private void StartOperation()

??????? {

??????????? Configuration cfg = new Configuration();

??????????? cfg.AddAssembly("NHibernate. Examples");???????????

??????????? ISessionFactory factory = cfg.BuildSessionFactory();

??????????? session = factory.OpenSession();??????????

??????????? tx = session.BeginTransaction();

??????? }

?

??????? private void HandleException(HibernateException e)

??????? {

??????????? tx.Rollback();

????????? ??throw e;

??????????? //注:你可以在此寫自己的異常處理,如記錄日志...

??????? }

??? }

?

我們將通用的CRUD方法(包括save/update/delete/find)都放到了AbstractDAO類中,并將這些方法設為protected,這樣只有子類可調用它們。看看我們現在繼承自AbstractDAOUserDAO是不是簡化了:

??? public class UserDAO : AbstractDAO

??? {

??????? public void Create(User newUser)

??????? {

??????????? base.Save(newUser);

??????? }

?

??????? public void Update(User newUser)

??????? {

??????????? base.Update(newUser);

??????? }

?

??????? public void Delete(User user)

??????? {

??????????? base.Delete(user);

??????? }

?

??????? public User Find(string id)

??????? {

??????????? return (User)base.Find(typeof(User), id);

??????? }

?

??????? public IList FindAll()

??????? {

??????????? return (IList)base.FindAll(typeof(User));

??????? }????????????

?

??? }

?

哈哈,UserDAO中該有的有,不該有的沒有了,世界看起來清爽多了!呼吸下新鮮的空氣吧,不用為寫更多的實體DAO類發愁了(如果還有代碼自動生成工具那就更好了----懶惰的程序員,呵呵J)!

不過,不要高興的太早,還沒完呢!

?

三、提高效率(引入單例模式)

看看AbstractDAO中每個CRUD方法都要調用的函數StartOperation()它包含創建ISessionFactory對象的核心代碼,這個創建過程需要加載NHibernate映射文件信息,內存開銷非常大,每個CRUD方法都要進行重復的創建,這還得了!還好我們有Singleton(單例模式)對付他!Singleton保證了一個類只被實例化一次,它將避免我們的重復加載映射文件信息的問題。以下是我們的實現:

public sealed class NHibernateFactory

??? {

??????? private static volatile ISessionFactory factory;

??????? private static object syncRoot = new Object();

??????? private NHibernateFactory() { }

?

??????? public static ISessionFactory BuildIfNeeded()

??????? {

??????????? if (factory == null)

??????????? {

??????????????? lock (syncRoot)

??????????????? {

??????????????????? if (factory == null)

?? ?????????????????{

??????????????????????? Configuration cfg = new Configuration();

??????????????????????? cfg.AddAssembly("NHibernate. Examples");

??????????????????????? factory = cfg.BuildSessionFactory();

??????????????????? }

??????????????? }

??????????? }

??????????? return factory;

??????? }

?

??????? //----------------------------------

??????? static public ISession OpenSession()

??????? {

??????????? NHibernateFactory.BuildIfNeeded();

??????????? ISession session = factory.OpenSession();

? ??????????return session;

??????? }

??? }

?

(注:本實現參考了MSDNhttp://msdn2.microsoft.com/zh-cn/library/ms998558.aspx 《在 C# 中實現 Singleton》中的內容,有關Singleton或更多設計模式推薦閱讀《大話設計模式》一書,很適合初學者的一本好書!)

有了單例的NHibernateFactory,我們的StartOperation()將變為:

private void StartOperation()

??????? {

??????????? session = NHibernateFactory.OpenSession();

??????????? tx = session.BeginTransaction();

??????? }

?

啊哈,恭喜你成功進階!

?

聽說SpringHibernate有更好的封裝,那么Spring.NET中應該也有對NHibernate的封裝吧,有空再說J

?

注:本文內容參考了《Hibernate Quickly中文版》P144-154.

文中內容不妥之處,敬請各位高手指教!

?

本文示例源碼下載:/Files/bluesky521/NHibernateQuickStart3.rar

測試環境:單機安裝Win2003SP2 + SQL2000 + .NET2.0 + VS2005

轉載于:https://www.cnblogs.com/yangjunwl/articles/1112482.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/380128.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/380128.shtml
英文地址,請注明出處:http://en.pswp.cn/news/380128.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

eclipse快捷鍵

Java開發工具(Eclipse的視窗和視圖概述) A:視窗 每一個基本的窗體被稱為視窗 PackageExplorer 顯示項目結構&#xff0c;包&#xff0c;類&#xff0c;及資源Outline 顯示類的結構&#xff0c;方便查找&#xff0c;識別&#xff0c;修改Console 程序運行的結果在該窗口顯示Hie…

【匯編語言】除法(DIV/IDIV)

除法&#xff08;DIV/IDIV&#xff09; 目錄除法&#xff08;DIV/IDIV&#xff09;DIV(unsigned divide)無符號數除法IDIV(signed divide)有符號數除法DIV(unsigned divide)無符號數除法 格式&#xff1a;DIV SRC 操作&#xff1a; SRCSRCSRC為字節時&#xff0c;(AL)←(AX)/…

java 方法 示例_Java集合syncedSortedSet()方法與示例

java 方法 示例集合類SynchronizedSortedSet()方法 (Collections Class synchronizedSortedSet() method) synchronizedSortedSet() method is available in java.util package. java.util軟件包中提供了sharedSortedSet ()方法 。 synchronizedSortedSet() method is used to …

遠控免殺專題(17)-Python-Rootkit免殺

免殺能力一覽表 幾點說明&#xff1a; 1、上表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家桶…

項目管理軟件應用淺析(轉)

項目管理是在一定的約束條件下&#xff0c;以高效率地實現項目業主的目標為目的&#xff0c;以項目經理個人負責制為基礎和以項目為獨立實體進行經濟核算&#xff0c;并按照項目內在的邏輯規律進行有效的計劃、組織、協調、控制的系統管理活動。項目管理的核心技術是網絡計劃技…

斜視角的討論(轉)

http://school.ogdev.net/listshow.asp?page4&typeid0&categoryid5&id0&ListType2 目 錄 1.1 地圖和地表 1.2 斜視角游戲中的視角 1.3 Tile圖片的拼接 1.4 不同地表間的過渡 1.5 地圖數據結構的定義 --------------------------------------------------…

計算機網絡(湖科大教書匠)

計算機網絡&#xff08;湖科大教書匠&#xff09; 本文檔為教學視頻【計算機網絡微課堂&#xff08;有字幕無背景音樂版&#xff09;_嗶哩嗶哩_bilibili】的摘錄 目錄計算機網絡&#xff08;湖科大教書匠&#xff09;一、緒論1.2 因特網概述1.2.1 網絡、互連網&#xff08;互聯…

經緯度

題目描述 給定地球的兩個經緯度坐標&#xff0c;問這兩個點的直線距離。假設地球為球體&#xff0c;半徑為6371009米。 輸入描述: 第一行一個整數T表示數據組數。 接下來n行&#xff0c;每行四個數lat1, lng1, lat2, lng2分別表示兩個點的經緯度。 正數表示北緯和東經。 …

遠控免殺專題(18)-ASWCrypter免殺

免殺能力一覽表 幾點說明&#xff1a; 1、上表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家桶…

Hibernate 筆記4 實現對數據庫的增刪改查

1 準備 首先在mysql數據庫中建表User,并添加相關信息。 user表結構如下。 ---------------------------------------------------------| Field | Type | Null | Key | Default | Extra |------------------------------------------------…

Direct3D中的繪制(3)

立方體——只比三角形稍微復雜一點&#xff0c;這個程序渲染一個線框立方體。 這個簡單的繪制和渲染立方體的程序的運行結果如下圖所示&#xff1a; 源程序&#xff1a; /************************************************************************************** Renders a …

遠控免殺專題(19)-nps_payload免殺

免殺能力一覽表 幾點說明&#xff1a; 1、上表中標識 √ 說明相應殺毒軟件未檢測出病毒&#xff0c;也就是代表了Bypass。 2、為了更好的對比效果&#xff0c;大部分測試payload均使用msf的windows/meterperter/reverse_tcp模塊生成。 3、由于本機測試時只是安裝了360全家桶…

VS2005中使用WebDeploymentProject的問題

近來做Web項目&#xff0c;VS2005中發布網站時默認發布大批的程序集&#xff0c;這給升級網站時造成很大麻煩&#xff0c;所以偶從MS下載了個WebDeploymentProject的插件&#xff08;下載地址http://download.microsoft.com/download/c/c/b/ccb4877f-55f7-4478-8f16-e41886607a…

操作系統中的多級隊列調度

多級隊列調度 (Multilevel queue scheduling) Every algorithm supports a different class of process but in a generalized system, some process wants to be scheduled using a priority algorithm. While some process wants to remain in the system (interactive proce…

編寫一程序,輸入一個字符串,查找該字符串中是否包含“abc”。

import java.lang.String.*;//這里調用java.long.String.contains()方法&#xff1b; import java.util.Scanner; public class shit {public static void main(String[] args) {Scanner wsq new Scanner(System.in);String str wsq.next();boolean status str.contains(&qu…

顯示消息提示對話框(WebForm)

1: /// <summary>2: /// 顯示消息提示對話框。3: /// Copyright (C) Maticsoft4: /// </summary>5: public class MessageBox6: { 7: private MessageBox()8: { 9: }10: 11: …

借助格式化輸出過canary保護

0x01 canary保護機制 棧溢出保護是一種緩沖區溢出攻擊緩解手段&#xff0c;當函數存在緩沖區溢出攻擊漏洞時&#xff0c;攻擊者可以覆蓋棧上的返回地址來讓shellcode能夠得到執行。當啟用棧保護后&#xff0c;函數開始執行的時候會先往棧里插入cookie信息&#xff0c;當函數真…

什么叫灰度圖

任何顏色都有紅、綠、藍三原色組成&#xff0c;假如原來某點的顏色為RGB(R&#xff0c;G&#xff0c;B)&#xff0c;那么&#xff0c;我們可以通過下面幾種方法&#xff0c;將其轉換為灰度&#xff1a; 1.浮點算法&#xff1a;GrayR*0.3G*0.59B*0.11 2.整數方法&#xff1a;Gra…

各抓包軟件的之間差異_系統軟件和應用程序軟件之間的差異

各抓包軟件的之間差異什么是軟件&#xff1f; (What is Software?) Software is referred to as a set of programs that are designed to perform a well-defined function. A program is a particular sequence of instructions written to solve a particular problem. 軟件…

輸入一字符串,統計其中有多少個單詞(單詞之間用空格分隔)(java)

import java.util.*; class Example3{public static void main(String args[]){Scanner sc new Scanner(System.in);String s sc.nextLine();//這里的sc.nextLine&#xff08;&#xff09;空格也會記數&#xff1b;StringTokenizer st new StringTokenizer(s," ")…