對使用CodeSmith模板生成NHibernate的代碼的分析

?????? CodeSmith是我們常用的代碼生成工具,其跟據不同的模板生成不同代碼的方式能大大加快我們的項目開發,減少重復勞動。NHibernate模板就是其常用模板之一。從這里可以下載到最新的模板文件。現在最新的版本為NHibernate-v1.2.1.2125,可以生成NHibernate1.2,2.1,3.0的代碼。我下載的稍早,是NHibernate-v1.1.7.2056,最高生成2.1的代碼,不過大同小異,就以我下載的版本來進行分析吧。

?

? ? ? 基本生成操作就不說了,官網上有講解的視頻,也有大把的網友做了專門的教程。代碼生成后,主要分為五大塊:

????? 1.Base塊,也就是基類塊,這里放有BusinessObjects塊,ManagerObjects塊,UnitTests塊的基類,還包括一個作者提供我們的一個管理NH的ISession的小模塊:NHibernateSessionManage塊。

? ? ? 2.BusinessObjects塊,也就是我們常說的實體(Entity/Model)塊。里面放置著與數據庫表一一對應的各個實體。

? ? ? 3.HbmMaps塊,NH必用,不多講。

? ? ? 4.ManagerObjects塊,也就是我們常說的BL層,里面包括了對每個實體的操作類,命名方式類似于XXXManage等等。另外還有一個小工廠,通過不同的方法實例化不同的管理類,比較簡單,不表。

? ? ? 5.UnitTests塊,測試用例塊,這不是我們今天談的重點,故不多述。

?

? ? ? 從上面可以看到,NH模板生成的代碼是典型的三層架構式代碼,采用的架構模式是活動記錄式。 更詳細的概念描述請自行Google,或者參見我另兩遍博文:業務邏輯架構模式(事務腳本,表模塊,活動記錄,領域模型),再談業務邏輯架構模式(事務腳本,表模塊,活動記錄,領域模型)。

? ? ? 由于Base塊里面的基類與下面三塊里的子類的關系較大,所以我將按照BusinessObjects塊,ManagerObjects塊,NHibernateSessionManage塊的順序來講述,在講述的過程中直接將基類一起表述。例子就參見下面的一張圖,其中Aim是實體類,AimManage是其對應的管理類。

? ? ??

? ? ? 首先是BusinessObjects塊,其實我們更常見的叫法是實體層。Aim是我們自己的實體,BusinessBase<T>是其基類,其中T這個泛型是指主鍵的類型,如果是聯合主鍵,這里則不會是基本類型,而是會單獨生成一個類,這個類的屬性與聯合主鍵的每一個子元素一一對應。BusinessBase<T>實現了IBusinessBase<T>接口,在這個接口里規定了一個很重要的屬性:Id,其類型由T來指定,這表明了所有表的主鍵的在代碼里都叫Id。當然,如果實際的表中的主鍵不叫Id也是沒有關系的,實體的配置文件hbm.xml可以解決這個問題。這個接口還有兩個方式:GetHashCode和Equals,比較簡單,不多表。

?

? ? ? 再來看ManagerObjects塊,對于這我們也有更常見的叫法:BL層或者是業務邏輯層。

?????

????? 從上向下講,最開始是個IManagerBase<T, TKey>接口,其中T是指其管理的實體類別,TKey是其管理的實體的主鍵類型。在這個接口中定義了常見的實體操作方式:增刪改和各種形勢的通用的查詢。ManagerBase<T, TKey>類則是其具體的實現。IAimManage是具體實體管理類的接口,里面定義了具體實體所具有的特定的操作方法,注意,這里繼承了IManagerBase<T, TKey>接口,這是很重要的一點,等下表述。最后是AimManage類,其繼承了ManagerBase<T, TKey>類和IAimManage接口。從前者獲取通用操作的實體,從后者獲取定義的特定操作并由自己來實現。這里就要講為什么IAimManage接口要繼承IManagerBase<T, TKey>。從編譯的角度來講,前者不繼承后者依然可以通過編譯,但從我們架構代碼的角度來講,當編碼中我們要操作AimManage類時,有兩種方式,一種是直接通過本類型操作:

AimManage?manage?=?new?AimManage();

一種是通過接口操作:

IAimManage?manage?=?new?AimManage();

為了減少代碼耦合,通過接口操作是比較理想的方式。如果前者不繼承后者,當出現后者的代碼時,我們就無法通過manage來操作AimManage類從ManagerBase<T, TKey>類繼承到的通用操作了。換種說法,由于ManagerBase<T, TKey>類繼承并實現了IManagerBase<T, TKey>接口,AimManage類又繼承了ManagerBase<T, TKey>類,那么實際上AimManage類間接繼承并實現了IManagerBase<T, TKey>接口。現在AimManage類又繼承并實現了IAimManage接口,從多繼承的角度來講,各個接口只能操作其子類從本接口繼承而來的屬性與方法,如下圖:

?

如果IAimManage接口沒有繼承IManagerBase接口,那當代碼是這么寫的時候:

IAimManage?manage?=?new?AimManage();?

變量manage是無法執行A()方法的,因為A()方法從IManagerBase接口而來。

?

? ? ? 最后看看NHibernateSessionManage塊,這是作者為我們提供的一個Session管理模塊,包括兩個類與兩個接口。這個模塊通過接口的方式與其它模塊交互的少,故不多表,主要講講兩個類的使用:NHibernateSessionManager類與NHibernateSession類。NHibernateSession類是作者為我們重新封裝的Session類,他將始的ISession接口封裝了進去,目的是代替NH原始的ISession接口。里面有兩個重要的成員ISession和ITransaction。其中ISession就是NH的原始的ISession接口。由于他在這里將原始的ISession接口封裝了進去,通過其操作事務就不是很方便,于是作者就使用成員ITransaction將ISession內的ITransaction引用出來,并寫了一大堆方法來完成對事務的操作。還有一個方法:GetISession()來獲取原始的ISession。

?

????? NHibernateSessionManager類是具體的Session管理類。他通過靜態變量Instance實現了單例模式。他有一個重要的屬性Session和一個重要的方法CreateISession()。通過Session屬性來獲取本次操作的NHibernateSession類。可以看到,作者將每次操作的NHibernateSession放到了緩存中(webForm與winForm放置的地方不同),提高了性能。CreateISession()方法則是真正獲取原始ISession的方法,NHibernateSession類的GetISession()方法調用的也是他。

public?ISession?GetISession()
{
????
if?(iSession?==?null)
????????iSession?
=?NHibernateSessionManager.Instance.CreateISession();
????
return?iSession;
}

?????? 回到ManagerBase<T, TKey>類,在其兩個構造函數中:

public?ManagerBase()
????:?
this(NHibernateSessionManager.Instance.Session)?{?}
public?ManagerBase(INHibernateSession?session)
{
????
this.session?=?session;
????
this.session.IncrementRefCount();
}

?????? 默認就是調用NHibernateSessionManager類單例實例的Session屬性,或者通過自定義INHibernateSession來注入。

?

? ? ? 以上就是代碼分析的全過程,可以看出,生成的代碼精干緊湊,使用方便,是我們學習三層架構模式,活動記錄模式和生產實踐的良好示范。

轉載于:https://www.cnblogs.com/ljzforever/archive/2011/03/14/1983121.html

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

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

相關文章

若川誠邀你加源碼共讀群,每周一起學源碼

小提醒&#xff1a;若川視野公眾號面試、源碼等文章合集在菜單欄中間【源碼精選】按鈕&#xff0c;歡迎點擊閱讀&#xff0c;也可以星標我的公眾號&#xff0c;便于查找。回復pdf&#xff0c;可以獲取前端優質書籍。最近我創建了一個源碼共讀的前端交流群&#xff0c;希望嘗試幫…

matlab 規范,matlab-代碼-規范

matlab-代碼-規范 1. 標識符命名原則 標識符的名字應當直觀&#xff0c;其長度應當符合“最小長度&#xff0c;最大信息量”原則。 1) 非矩陣變量&#xff1a; 變量名應該以小寫字母開頭的大小寫混合形式 譬如&#xff1a;shadowFadingTable&#xff0c;servingSector&#xf…

zoom視頻會議官網_人性化視頻會議的空間(Zoom等)

zoom視頻會議官網第二部分&#xff1a;房間的創造力 (Part Two: The Creativity of Rooms) In Part One I shared thoughts on how virtual spaces can often leave little room to embody our most human selves. The lack of a public sphere that parallels our shared publ…

KOFLive Postmortem

為期兩個月的團隊項目完成了&#xff0c;我們的游戲也已經發布。在這個名叫KOFLive的小游戲里&#xff0c;我們集成了五個真人角色&#xff0c;每個角色有拳腳基本招數以及三個小招、一個大招&#xff0c;硬值、防御、集氣、雙人對戰、人機對戰、練習模式等格斗游戲的Feature基…

單調隊列優化多重背包

就是按照 % 體積的余數來分組&#xff0c;每組單調隊列優化。 直接上模板好了。 1 #include <bits/stdc.h>2 3 typedef long long LL;4 const int N 100010;5 6 int n, V, cnt[N], cost[N];7 LL f[2][N], val[N], p[N], top, head;8 9 inline void Max(LL &a, const…

2021年7月 蝦皮、貨拉拉、有贊等面經總結

大家好&#xff0c;我是若川&#xff0c;加我微信 ruochuan12 進源碼交流群。今天分享一篇7月份新鮮出爐的面經&#xff0c;文章較長&#xff0c;可以收藏再看。學習源碼系列、面試、年度總結、JS基礎系列。本文來自作者幾米陽光 投稿 原文鏈接&#xff1a;https://juejin.cn/p…

Oracle對表名大小寫敏感嗎,讓Oracle 大小寫敏感 表名 字段名 對像名

一、解決方案1、在表名、字段名、對象名上加上雙引號&#xff0c;即可實現讓oracle大小寫區分。2、但是這又引起了另一個問題&#xff1a;在數據庫操作中&#xff0c;sql語句中相應的表名、字段名、對象名上一定要加雙引號。解決辦法是&#xff1a;使用"\"轉義。如&a…

谷歌抽屜_Google(最終)會殺死導航抽屜嗎?

谷歌抽屜A couple of months ago Google has celebrated with enthusiasm 15 years of Google Maps, one of the most used and appreciated services worldwide from the company.幾個月前&#xff0c;Google熱情地慶祝Google Maps誕生15周年&#xff0c;這是該公司在全球范圍…

MySQL——安裝

MySQL——安裝 1. 下載源&#xff1a; http://repo.mysql.com/yum/mysql-8.0-community/el/7/x86_64/mysql80-community-release-el7-2.noarch.rpm 該源目前為8.0版本&#xff0c;如果需要最新請退至根目錄找。 1wget http://repo.mysql.com/yum/mysql-8.0-community/el/7/x86_…

寫給初中級前端的高級進階指南等

大家好&#xff0c;我是若川。話不多說&#xff0c;這一次花了幾小時精心為大家挑選了20余篇好文&#xff0c;供大家閱讀學習。本文閱讀技巧&#xff0c;先粗看標題&#xff0c;感興趣可以都關注一波&#xff0c;絕對不虧。程序員成長指北考拉妹子&#xff0c;一個有趣的且樂于…

oracle for函數,oracle分區表述的FOR語句(一)

指定一個分區除了使用分區名稱外&#xff0c;很多時候還可以使用FOR語句。從11g開始&#xff0c;對分區進行操作的時候&#xff0c;不僅可以使用分區名稱&#xff0c;還可以使用FOR語句。在10g中&#xff0c;MERGE RANGE分區的語句如下&#xff1a;SQL> SELECT * FROM V$VER…

axure9控件樹 rp_如何在Axure RP 9中創建分段控件

axure9控件樹 rpSegmented controls are not very easy to tackle in prototyping. This is especially true when you have more than 2 segments. This article will show you how to create a segmented control with 3 segments in Axure in just 2 simple steps. The tech…

stack

1. 棧數據結構簡單介紹 2. 簡單實現代碼及stl中stack簡單使用 3. 代碼下載 1. 棧數據結構簡單介紹 棧是這樣的一種數據結構&#xff0c;遵循“先進后出”的原則。在stack上定義如下的operations&#xff1a; 1. 判空 2. 入棧push 3. 出棧pop&#xff0c;在棧的不同實現版本中&…

MacOS搭建環境

基礎環境 從AppStore下載 有道云筆記微信網易云音樂Chrome瀏覽器postmanChrome插件云筆記剪報基礎命令 mac下別名vi ~/.bash_profile 添加 alias llls -alF alias lals -A alias lls -CF 保存后執行(不能有空格) source ~/.bash_profile復制代碼開發環境 PhpStorm 從官網下載Ph…

【送書-小姐姐配音】低代碼平臺的核心價值與優勢

大家好&#xff0c;我是若川。記得點上方聽小姐姐配音&#xff0c;識別下方二維碼加我微信 ruochuan12&#xff0c;明天&#xff08;8月8日&#xff09;晚8點在朋友圈發動態。點贊抽3位小伙伴包郵送《實戰低代碼》&#xff0c;細則見動態。最近組織了源碼共讀活動&#xff0c;每…

oracle靜默安裝集群,靜默安裝Oracle數據庫10g篇

靜默安裝Oracle數據庫10g篇以下是在Linux系統上靜默安裝Oracle數據庫10g的實踐過程&#xff0c;主要分為以下兩個步驟&#xff1a;Step 1&#xff0e;靜默安裝Oracle數據庫10g軟件1. 使用OUI錄制響應文件&#xff0c;記錄安裝過程執行以下命令&#xff0c;然后在OUI中根據提示執…

sketch鋼筆工具_設計工具(Sketch,Adobe XD,Figma和InVision Studio)中奇怪的一項功能

sketch鋼筆工具When you build a new product that is very similar to the existing products in the market, the designers and product managers tend to do certain features different from others. Sometimes this brings a good change, sometimes worse.當您構建與市場…

modprobe:FATAL: could not load /lib/modules/2.6.35-22-generic/modules.dep No such file or directory

給ubuntu升級到10.10 &#xff0c;開機可能出現錯誤modprobe:FATAL: could not load /lib/modules/2.6.35-22-generic/modules.dep No such file or directorymodprobe:FATAL: could not load /lib/modules/2.6.35-22-generic/modules.dep No such file or directory解決辦法&a…

Python進階:如何將字符串常量轉化為變量?

2019獨角獸企業重金招聘Python工程師標準>>> 前幾天&#xff0c;我們Python貓交流學習群 里的 M 同學提了個問題。這個問題挺有意思&#xff0c;經初次討論&#xff0c;我們認為它無解。 然而&#xff0c;我認為它很有價值&#xff0c;應該繼續思考怎么解決&#xf…

怎么在matlab中圖像中外接矩形,Matlab 最小外接矩形

Matlab 中并沒有發現最小外接矩形的代碼&#xff0c;為了方便下面提供最小外接矩形的代碼&#xff1a;注&#xff1a;這個函數是源于網上找到的代碼的改進版&#xff0c;原版不能檢測水平線或者垂直線function [rectx,recty,area,perimeter] minboundrect(x,y,metric)% minbou…