RFID世界網(wǎng) >
技術(shù)文章 >
物流 >
正文
數(shù)據(jù)訪問(wèn)中間件及其在物流倉(cāng)儲(chǔ)支撐平臺(tái)中的應(yīng)用
作者:鮑鵬
來(lái)源:通信市場(chǎng)網(wǎng)
日期:2011-01-07 09:26:19
摘要:本文分析現(xiàn)有的數(shù)據(jù)庫(kù)訪問(wèn)中間件的現(xiàn)狀,在物流倉(cāng)儲(chǔ)綜合支撐平臺(tái)中應(yīng)用輕量級(jí)的ORM框架,介紹數(shù)據(jù)訪問(wèn)中間件的使用,通過(guò)具體實(shí)例表明,使用數(shù)據(jù)訪問(wèn)中間件可以簡(jiǎn)化數(shù)據(jù)存取訪問(wèn)過(guò)程,使擴(kuò)展性得到了大大的增強(qiáng),并可以最大限度的不影響上層的應(yīng)用程序的結(jié)構(gòu),減少系統(tǒng)維護(hù)的難度。
引言
傳統(tǒng)的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)對(duì)于數(shù)據(jù)庫(kù)操作的復(fù)雜性,以及擴(kuò)展性差等問(wèn)題已漸漸制約分布式應(yīng)用集成的需要,利用新技術(shù),研究和開(kāi)發(fā)新的數(shù)據(jù)庫(kù)訪問(wèn)中間件成為數(shù)據(jù)庫(kù)研究領(lǐng)域的主要方向之一。中間件技術(shù)將傳統(tǒng)的客戶機(jī)/服務(wù)器體系結(jié)構(gòu)擴(kuò)展為三層體系結(jié)構(gòu)模式,即客戶機(jī)-中間件-服務(wù)器體系模式。
本文所述系統(tǒng)為物流倉(cāng)儲(chǔ)綜合支撐平臺(tái),用于支撐多種基本物流業(yè)務(wù),包括報(bào)關(guān)(單證)、存儲(chǔ)、運(yùn)輸、訂艙等基本業(yè)務(wù)類型以及由這些基本業(yè)務(wù)類型所組成的各種復(fù)合業(yè)務(wù)類型。系統(tǒng)采用表示層、業(yè)務(wù)處理層與數(shù)據(jù)存儲(chǔ)層三層結(jié)構(gòu)的CS架構(gòu),表示層的主要職責(zé)是為用戶提供信息以及提供交互。表示層細(xì)分為界面外觀層與界面邏輯層。業(yè)務(wù)邏輯層的主要職責(zé)是對(duì)用戶提交的輸入指令與數(shù)據(jù)做校驗(yàn),再加工后將數(shù)據(jù)提交到數(shù)據(jù)存儲(chǔ)層或?qū)?shù)據(jù)存儲(chǔ)層的數(shù)據(jù)提取后返回給表示層。數(shù)據(jù)存儲(chǔ)層主要職責(zé)是存儲(chǔ)用戶數(shù)據(jù)。其中數(shù)據(jù)訪問(wèn)層與事務(wù)處理層,使用Castle ActiveRecord框架作為數(shù)據(jù)庫(kù)持久層,框架提供對(duì)數(shù)據(jù)訪問(wèn)層與事務(wù)處理層的封裝。
數(shù)據(jù)訪問(wèn)中間件定義
中間件為可以為其他程序員服用、實(shí)現(xiàn)特定功能接口的程序包或服務(wù)。中間件在操作系統(tǒng)軟件,網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)之上,應(yīng)用軟件之下,總的作用是為處于上層的應(yīng)用程序提供開(kāi)發(fā)環(huán)境,幫助用戶高效、靈活的開(kāi)發(fā)和集成更加復(fù)雜的應(yīng)用軟件。IDC對(duì)中間件的定義為:中間件是一種獨(dú)立的系統(tǒng)軟件或服務(wù)程序,分布式應(yīng)用軟件借助這種軟件在不同的技術(shù)之間共享資源,中間件定位于客戶機(jī)服務(wù)器的操作系統(tǒng)之上,管理計(jì)算機(jī)資源和網(wǎng)絡(luò)通信。按照IDC的分類方法,中間件可分為六類:終端仿真、數(shù)據(jù)訪問(wèn)中間件、遠(yuǎn)程過(guò)程調(diào)用中間件、消息中間件、交易中間件、對(duì)象中間件。
本文涉及的數(shù)據(jù)訪問(wèn)中間件為中間件的一種,是指一切連接應(yīng)用程序和數(shù)據(jù)庫(kù)的軟件,位于客戶機(jī)服務(wù)器的操作系統(tǒng)之上,通過(guò)使用統(tǒng)一接口提供對(duì)運(yùn)行在多種平臺(tái)上的不同數(shù)據(jù)庫(kù)的訪問(wèn)。通過(guò)使用數(shù)據(jù)訪問(wèn)中間件,可擴(kuò)展性得到了大大的增強(qiáng),可以最大限度的不影響上層的應(yīng)用程序的結(jié)構(gòu),減少系統(tǒng)維護(hù)的難度。由于對(duì)于數(shù)據(jù)庫(kù)的操作都被封裝在數(shù)據(jù)庫(kù)訪問(wèn)中間件,用戶對(duì)數(shù)據(jù)的管理實(shí)現(xiàn)了對(duì)數(shù)據(jù)庫(kù)操作的透明性。
本文所述系統(tǒng)使用的數(shù)據(jù)庫(kù)訪問(wèn)中間件為Castle .Net 中的額ActiveRecord組件,它是一個(gè)輕量級(jí)的ORM組件,它在底層封裝了NHibernate. NHibernate是一個(gè)基于.Net,用于關(guān)系數(shù)據(jù)庫(kù)的對(duì)象持久化類庫(kù),它是著名的Hibernate的.Net版本,采用xml配置文件進(jìn)行關(guān)系的映射。在ActiveRecord中,則對(duì)這種方式進(jìn)行了進(jìn)一步的封裝,采用特性(Attribute)的方式進(jìn)行映射。
數(shù)據(jù)訪問(wèn)中間件實(shí)現(xiàn)
本系統(tǒng)采用表示層、業(yè)務(wù)處理層與數(shù)據(jù)存儲(chǔ)層三層結(jié)構(gòu)的CS架構(gòu)。如下圖所示為該系統(tǒng)項(xiàng)目軟件結(jié)構(gòu)如圖一所示。
由于本項(xiàng)目采用C/S架構(gòu),故僅主要使用Castle中的數(shù)據(jù)訪問(wèn)ORM框架Castle ActiveRecord。Castle ActiveRecord是Castle中提供的一個(gè)輕量級(jí)數(shù)據(jù)訪問(wèn)框架,它在底層封裝了NHibernate的操作,使用特性來(lái)代替映射文件,從而提供非常簡(jiǎn)潔的O/R映射(一對(duì)一、一對(duì)多,多對(duì)多關(guān)系等均可以表達(dá))。同時(shí),它還實(shí)現(xiàn)了對(duì)象的最基本的CRUD操作,這在很大程度上減少了開(kāi)發(fā)的工作量。另外,ActiveRecord支持HQL(Hibernate Query Language ),使開(kāi)發(fā)人員可以自定義一些復(fù)雜查詢。其他特性:多數(shù)據(jù)庫(kù)連接、支持事務(wù)處理、維護(hù)方便性。提供對(duì)數(shù)據(jù)訪問(wèn)層與事務(wù)處理層的封裝。
數(shù)據(jù)訪問(wèn)中間件的配置
ActiveRecord在底層封裝了NHibernate,在框架啟動(dòng)時(shí)需要指定相關(guān)的配置信息??梢允褂米约旱腦ML文件來(lái)保存配置信息,例如有一個(gè)AppConfig.xml的文件。
<activerecord>
<config>
<add
key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add
key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider" />
<add
key="hibernate.connection.connection_string" value="Data Source=.\SQLEXPRESS;Initial Catalog=DataBase;UID=sa;Password=password;" />
</config>
</activerecord>
創(chuàng)建ActiveRecord類
使用ActiveRecord中的配置關(guān)鍵字ActiveRecordAttributes、PrimaryKeyAttribute、PropertyAttribute等,為實(shí)體類配置表、字段、關(guān)系等映射信息。
使用ActiveRecordAttributes配置實(shí)體類,關(guān)聯(lián)映射信息。樣例如下:
默認(rèn)實(shí)體類名與數(shù)據(jù)庫(kù)表同名
[ActiveRecord()]
public class Transport_List : Transport_Department_Base
在實(shí)體類中,通過(guò)PrimaryKeyAttribute來(lái)指定表的主鍵
[PrimaryKey()]
public int Id
在ActiveRecord中通過(guò)PropertyAttribute來(lái)指定實(shí)體類屬性與數(shù)據(jù)庫(kù)中的字段映射。
[Property(“ForReimburse”)]
public string Reimburse_remark
在ActiveRecord中,允許直接對(duì)Field進(jìn)行映射,使用FieldAttribute。
[Field”CheckName”]
public string CheckName
配置關(guān)系映射
多對(duì)一關(guān)系可以使用BelongsToAttribute表示。
[BelongsTo("end_point_id")]
public Transport_Location End_point
一對(duì)多關(guān)系可以使用HasManyAttribute表示。
[HasMany(typeof(Signed_List),Table = "Signed_List",
ColumnKey = transport_list_id", Inverse = true, Cascade = ManyRelationCascadeEnum. AllDeleteOrphan, Lazy = true)]
public IList Signed_Lists
ActiveRecord還支持多對(duì)多關(guān)系,以及一對(duì)一關(guān)系。在ActiveRecord中把數(shù)據(jù)庫(kù)表之間的關(guān)聯(lián)關(guān)系采用對(duì)象間的聚合關(guān)系來(lái)表現(xiàn),然而這卻帶來(lái)一系列的性能上的問(wèn)題。就像在一對(duì)多中用到的例子Blog,使用Blog.Find(1)查找了一個(gè)Blog對(duì)象,也許我們只用到它,但事實(shí)它卻把該Blog所關(guān)聯(lián)的Post對(duì)象也讀取出來(lái)放在了內(nèi)存中,于是就需要有一種方法來(lái)實(shí)現(xiàn)只在需要Post對(duì)象的時(shí)候框架再自動(dòng)讀取。
要實(shí)現(xiàn)延遲加載,其實(shí)只要在HasAndBelongsToMany、HasManyAttribute的特性中使用Lazy=true。另外,使用延遲加載時(shí)還需要將當(dāng)前的Session保存下來(lái),否則ActiveRecord在實(shí)現(xiàn)延遲載入時(shí)找不到一個(gè)NHibernate的ISession而出錯(cuò)。為了保存當(dāng)前的Session我們必須使用new SessionScope()。
使用Scope以及schema相關(guān)方法
Scopes允許優(yōu)化一系列數(shù)據(jù)庫(kù)操作,以及為代碼塊加入業(yè)務(wù)語(yǔ)義。一個(gè)Scopes中的所有ActiveRecord的數(shù)據(jù)庫(kù)操作都是在同一個(gè)數(shù)據(jù)庫(kù)線程中執(zhí)行。如果使用了延遲加載,則必須使用SessionScope。包括SessionScope,TransactionScope以及Nested Transactions.
使用SessionScope過(guò)程如下:
using (new Castle.ActiveRecord.SessionScope())
{
SelectedBizList = new List<Business_List>();
for (int j = 0; j < selectedSheetList.Count ; j++)
{
selectedBiz=Business_List.Find(selectedSheetList[j].Id);
SelectedBizList.Add(selectedBiz);
}
}
使用TransactionScope過(guò)程如下:
using (TransactionScope btran = new TransactionScope())
{
try
{ myDriver.Create();
btran.VoteCommit(); }
catch
{ btran.VoteRollBack() }
}
Castle ActiveRecord提供了由實(shí)體類生成數(shù)據(jù)庫(kù)表的方法,它其實(shí)在底層是封裝了NHibernate.Tool.hbm2ddl中的SchemaExport。
既創(chuàng)建數(shù)據(jù)庫(kù)表的方法都是通過(guò)SchemaExport類來(lái)完成了,所有的這些方法都在ActiveRecordStarter中提供.
使用HQL查詢
ActiveRecord只提供了Find(id),F(xiàn)indAll()這樣兩個(gè)靜態(tài)的查詢方法,在實(shí)際查詢中比如綜合支撐平臺(tái)中對(duì)多種業(yè)務(wù)單的詳細(xì)查詢就不能滿足要求了,這方面ActiveRecord為我們提供了HQL語(yǔ)言的支持。HQL全名是Hibernate Query Language,它是一種完全面向?qū)ο蟮牟樵冋Z(yǔ)言。
SimpleQuery是一種最簡(jiǎn)單的查詢,它直接處理HQL語(yǔ)句,并返回一個(gè)集合,沒(méi)有復(fù)雜的參數(shù)處理,具體用法參考下例:
public static Driver[] FindDriversIs_inOrNot(bool is_in)
{ string hql = @"from Driver where Is_in = ? ";
Castle.ActiveRecord.Queries.SimpleQuery query = new Castle.ActiveRecord.Queries.SimpleQuery(typeof(Driver), hql, is_in);
return (Driver[])ActiveRecordBase.ExecuteQuery(query); }
ScalarQuery查詢也是一種簡(jiǎn)單的直接處理HQL的查詢,它也沒(méi)有復(fù)雜的參數(shù)處理,只不過(guò)返回的值不是集合而是單一的值,具體用法類似SimpleQuery。
HqlBasedQuery是最為強(qiáng)大的Query類,支持跨庫(kù)/跨基類聯(lián)合查詢;可以使用HqlBasedQuery來(lái)實(shí)現(xiàn)選定屬性查詢,返回的結(jié)果為ArrayList,結(jié)構(gòu)形式與SQL查詢類似,可每行作為一個(gè)Object,而后按順序提取字段值,具體用法參考下例:
public static string FindMaxSnOfOuterDriver()
{
string hql = ""; HqlBasedQuery query;
hql = @"select max(dir.Driver_sn) from Driver dir where dir.Is_in = 'False' ";
query = new HqlBasedQuery(typeof(Driver), hql);
IList result= (IList)ActiveRecordBase.ExecuteQuery(query);
if (result == null || result.Count == 0)
return "10000";
else
else return result[0].ToString();
}
小結(jié)
根據(jù)以上的介紹,利用ActiveRecord數(shù)據(jù)庫(kù)訪問(wèn)中間件,極大的簡(jiǎn)化了數(shù)據(jù)庫(kù)操作,可以擴(kuò)展數(shù)據(jù)庫(kù)系統(tǒng)的應(yīng)用范圍。這種中間件不僅適應(yīng)于局域網(wǎng),更加適應(yīng)于未來(lái)的基于廣域網(wǎng)的應(yīng)用程序。ActiveRecord數(shù)據(jù)訪問(wèn)中間件不僅跨平臺(tái),而且使用方便,并且擴(kuò)展性高。上述例子是以微軟的SQL SERVER作為數(shù)據(jù)庫(kù)應(yīng)用,如要擴(kuò)展到Oracle或其他數(shù)據(jù)庫(kù)只需更新其相應(yīng)的.Net插件即可。Castle的ActiveRecord底層將NHibernate封裝了起來(lái),使用起來(lái)感覺(jué)比Nhibernate方便多了,不用再去生成一個(gè)個(gè)的映射文件,調(diào)試和維護(hù)起來(lái)都方便了很多。
經(jīng)過(guò)在物流倉(cāng)儲(chǔ)綜合支撐平臺(tái)中應(yīng)用數(shù)據(jù)訪問(wèn)中間件,程序的開(kāi)發(fā)周期大大縮短,程序的可維護(hù)性,以及可擴(kuò)展性得到了提高,在信息管理平臺(tái)中使用數(shù)據(jù)訪問(wèn)中間件將是一個(gè)有效的解決方案。
傳統(tǒng)的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)對(duì)于數(shù)據(jù)庫(kù)操作的復(fù)雜性,以及擴(kuò)展性差等問(wèn)題已漸漸制約分布式應(yīng)用集成的需要,利用新技術(shù),研究和開(kāi)發(fā)新的數(shù)據(jù)庫(kù)訪問(wèn)中間件成為數(shù)據(jù)庫(kù)研究領(lǐng)域的主要方向之一。中間件技術(shù)將傳統(tǒng)的客戶機(jī)/服務(wù)器體系結(jié)構(gòu)擴(kuò)展為三層體系結(jié)構(gòu)模式,即客戶機(jī)-中間件-服務(wù)器體系模式。
本文所述系統(tǒng)為物流倉(cāng)儲(chǔ)綜合支撐平臺(tái),用于支撐多種基本物流業(yè)務(wù),包括報(bào)關(guān)(單證)、存儲(chǔ)、運(yùn)輸、訂艙等基本業(yè)務(wù)類型以及由這些基本業(yè)務(wù)類型所組成的各種復(fù)合業(yè)務(wù)類型。系統(tǒng)采用表示層、業(yè)務(wù)處理層與數(shù)據(jù)存儲(chǔ)層三層結(jié)構(gòu)的CS架構(gòu),表示層的主要職責(zé)是為用戶提供信息以及提供交互。表示層細(xì)分為界面外觀層與界面邏輯層。業(yè)務(wù)邏輯層的主要職責(zé)是對(duì)用戶提交的輸入指令與數(shù)據(jù)做校驗(yàn),再加工后將數(shù)據(jù)提交到數(shù)據(jù)存儲(chǔ)層或?qū)?shù)據(jù)存儲(chǔ)層的數(shù)據(jù)提取后返回給表示層。數(shù)據(jù)存儲(chǔ)層主要職責(zé)是存儲(chǔ)用戶數(shù)據(jù)。其中數(shù)據(jù)訪問(wèn)層與事務(wù)處理層,使用Castle ActiveRecord框架作為數(shù)據(jù)庫(kù)持久層,框架提供對(duì)數(shù)據(jù)訪問(wèn)層與事務(wù)處理層的封裝。
數(shù)據(jù)訪問(wèn)中間件定義
中間件為可以為其他程序員服用、實(shí)現(xiàn)特定功能接口的程序包或服務(wù)。中間件在操作系統(tǒng)軟件,網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)之上,應(yīng)用軟件之下,總的作用是為處于上層的應(yīng)用程序提供開(kāi)發(fā)環(huán)境,幫助用戶高效、靈活的開(kāi)發(fā)和集成更加復(fù)雜的應(yīng)用軟件。IDC對(duì)中間件的定義為:中間件是一種獨(dú)立的系統(tǒng)軟件或服務(wù)程序,分布式應(yīng)用軟件借助這種軟件在不同的技術(shù)之間共享資源,中間件定位于客戶機(jī)服務(wù)器的操作系統(tǒng)之上,管理計(jì)算機(jī)資源和網(wǎng)絡(luò)通信。按照IDC的分類方法,中間件可分為六類:終端仿真、數(shù)據(jù)訪問(wèn)中間件、遠(yuǎn)程過(guò)程調(diào)用中間件、消息中間件、交易中間件、對(duì)象中間件。
本文涉及的數(shù)據(jù)訪問(wèn)中間件為中間件的一種,是指一切連接應(yīng)用程序和數(shù)據(jù)庫(kù)的軟件,位于客戶機(jī)服務(wù)器的操作系統(tǒng)之上,通過(guò)使用統(tǒng)一接口提供對(duì)運(yùn)行在多種平臺(tái)上的不同數(shù)據(jù)庫(kù)的訪問(wèn)。通過(guò)使用數(shù)據(jù)訪問(wèn)中間件,可擴(kuò)展性得到了大大的增強(qiáng),可以最大限度的不影響上層的應(yīng)用程序的結(jié)構(gòu),減少系統(tǒng)維護(hù)的難度。由于對(duì)于數(shù)據(jù)庫(kù)的操作都被封裝在數(shù)據(jù)庫(kù)訪問(wèn)中間件,用戶對(duì)數(shù)據(jù)的管理實(shí)現(xiàn)了對(duì)數(shù)據(jù)庫(kù)操作的透明性。
本文所述系統(tǒng)使用的數(shù)據(jù)庫(kù)訪問(wèn)中間件為Castle .Net 中的額ActiveRecord組件,它是一個(gè)輕量級(jí)的ORM組件,它在底層封裝了NHibernate. NHibernate是一個(gè)基于.Net,用于關(guān)系數(shù)據(jù)庫(kù)的對(duì)象持久化類庫(kù),它是著名的Hibernate的.Net版本,采用xml配置文件進(jìn)行關(guān)系的映射。在ActiveRecord中,則對(duì)這種方式進(jìn)行了進(jìn)一步的封裝,采用特性(Attribute)的方式進(jìn)行映射。
數(shù)據(jù)訪問(wèn)中間件實(shí)現(xiàn)
本系統(tǒng)采用表示層、業(yè)務(wù)處理層與數(shù)據(jù)存儲(chǔ)層三層結(jié)構(gòu)的CS架構(gòu)。如下圖所示為該系統(tǒng)項(xiàng)目軟件結(jié)構(gòu)如圖一所示。
由于本項(xiàng)目采用C/S架構(gòu),故僅主要使用Castle中的數(shù)據(jù)訪問(wèn)ORM框架Castle ActiveRecord。Castle ActiveRecord是Castle中提供的一個(gè)輕量級(jí)數(shù)據(jù)訪問(wèn)框架,它在底層封裝了NHibernate的操作,使用特性來(lái)代替映射文件,從而提供非常簡(jiǎn)潔的O/R映射(一對(duì)一、一對(duì)多,多對(duì)多關(guān)系等均可以表達(dá))。同時(shí),它還實(shí)現(xiàn)了對(duì)象的最基本的CRUD操作,這在很大程度上減少了開(kāi)發(fā)的工作量。另外,ActiveRecord支持HQL(Hibernate Query Language ),使開(kāi)發(fā)人員可以自定義一些復(fù)雜查詢。其他特性:多數(shù)據(jù)庫(kù)連接、支持事務(wù)處理、維護(hù)方便性。提供對(duì)數(shù)據(jù)訪問(wèn)層與事務(wù)處理層的封裝。
數(shù)據(jù)訪問(wèn)中間件的配置
ActiveRecord在底層封裝了NHibernate,在框架啟動(dòng)時(shí)需要指定相關(guān)的配置信息??梢允褂米约旱腦ML文件來(lái)保存配置信息,例如有一個(gè)AppConfig.xml的文件。
<activerecord>
<config>
<add
key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add
key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider"value="NHibernate.Connection.DriverConnectionProvider" />
<add
key="hibernate.connection.connection_string" value="Data Source=.\SQLEXPRESS;Initial Catalog=DataBase;UID=sa;Password=password;" />
</config>
</activerecord>
創(chuàng)建ActiveRecord類
使用ActiveRecord中的配置關(guān)鍵字ActiveRecordAttributes、PrimaryKeyAttribute、PropertyAttribute等,為實(shí)體類配置表、字段、關(guān)系等映射信息。
使用ActiveRecordAttributes配置實(shí)體類,關(guān)聯(lián)映射信息。樣例如下:
默認(rèn)實(shí)體類名與數(shù)據(jù)庫(kù)表同名
[ActiveRecord()]
public class Transport_List : Transport_Department_Base
在實(shí)體類中,通過(guò)PrimaryKeyAttribute來(lái)指定表的主鍵
[PrimaryKey()]
public int Id
在ActiveRecord中通過(guò)PropertyAttribute來(lái)指定實(shí)體類屬性與數(shù)據(jù)庫(kù)中的字段映射。
[Property(“ForReimburse”)]
public string Reimburse_remark
在ActiveRecord中,允許直接對(duì)Field進(jìn)行映射,使用FieldAttribute。
[Field”CheckName”]
public string CheckName
配置關(guān)系映射
多對(duì)一關(guān)系可以使用BelongsToAttribute表示。
[BelongsTo("end_point_id")]
public Transport_Location End_point
一對(duì)多關(guān)系可以使用HasManyAttribute表示。
[HasMany(typeof(Signed_List),Table = "Signed_List",
ColumnKey = transport_list_id", Inverse = true, Cascade = ManyRelationCascadeEnum. AllDeleteOrphan, Lazy = true)]
public IList Signed_Lists
ActiveRecord還支持多對(duì)多關(guān)系,以及一對(duì)一關(guān)系。在ActiveRecord中把數(shù)據(jù)庫(kù)表之間的關(guān)聯(lián)關(guān)系采用對(duì)象間的聚合關(guān)系來(lái)表現(xiàn),然而這卻帶來(lái)一系列的性能上的問(wèn)題。就像在一對(duì)多中用到的例子Blog,使用Blog.Find(1)查找了一個(gè)Blog對(duì)象,也許我們只用到它,但事實(shí)它卻把該Blog所關(guān)聯(lián)的Post對(duì)象也讀取出來(lái)放在了內(nèi)存中,于是就需要有一種方法來(lái)實(shí)現(xiàn)只在需要Post對(duì)象的時(shí)候框架再自動(dòng)讀取。
要實(shí)現(xiàn)延遲加載,其實(shí)只要在HasAndBelongsToMany、HasManyAttribute的特性中使用Lazy=true。另外,使用延遲加載時(shí)還需要將當(dāng)前的Session保存下來(lái),否則ActiveRecord在實(shí)現(xiàn)延遲載入時(shí)找不到一個(gè)NHibernate的ISession而出錯(cuò)。為了保存當(dāng)前的Session我們必須使用new SessionScope()。
使用Scope以及schema相關(guān)方法
Scopes允許優(yōu)化一系列數(shù)據(jù)庫(kù)操作,以及為代碼塊加入業(yè)務(wù)語(yǔ)義。一個(gè)Scopes中的所有ActiveRecord的數(shù)據(jù)庫(kù)操作都是在同一個(gè)數(shù)據(jù)庫(kù)線程中執(zhí)行。如果使用了延遲加載,則必須使用SessionScope。包括SessionScope,TransactionScope以及Nested Transactions.
使用SessionScope過(guò)程如下:
using (new Castle.ActiveRecord.SessionScope())
{
SelectedBizList = new List<Business_List>();
for (int j = 0; j < selectedSheetList.Count ; j++)
{
selectedBiz=Business_List.Find(selectedSheetList[j].Id);
SelectedBizList.Add(selectedBiz);
}
}
使用TransactionScope過(guò)程如下:
using (TransactionScope btran = new TransactionScope())
{
try
{ myDriver.Create();
btran.VoteCommit(); }
catch
{ btran.VoteRollBack() }
}
Castle ActiveRecord提供了由實(shí)體類生成數(shù)據(jù)庫(kù)表的方法,它其實(shí)在底層是封裝了NHibernate.Tool.hbm2ddl中的SchemaExport。
既創(chuàng)建數(shù)據(jù)庫(kù)表的方法都是通過(guò)SchemaExport類來(lái)完成了,所有的這些方法都在ActiveRecordStarter中提供.
使用HQL查詢
ActiveRecord只提供了Find(id),F(xiàn)indAll()這樣兩個(gè)靜態(tài)的查詢方法,在實(shí)際查詢中比如綜合支撐平臺(tái)中對(duì)多種業(yè)務(wù)單的詳細(xì)查詢就不能滿足要求了,這方面ActiveRecord為我們提供了HQL語(yǔ)言的支持。HQL全名是Hibernate Query Language,它是一種完全面向?qū)ο蟮牟樵冋Z(yǔ)言。
SimpleQuery是一種最簡(jiǎn)單的查詢,它直接處理HQL語(yǔ)句,并返回一個(gè)集合,沒(méi)有復(fù)雜的參數(shù)處理,具體用法參考下例:
public static Driver[] FindDriversIs_inOrNot(bool is_in)
{ string hql = @"from Driver where Is_in = ? ";
Castle.ActiveRecord.Queries.SimpleQuery query = new Castle.ActiveRecord.Queries.SimpleQuery(typeof(Driver), hql, is_in);
return (Driver[])ActiveRecordBase.ExecuteQuery(query); }
ScalarQuery查詢也是一種簡(jiǎn)單的直接處理HQL的查詢,它也沒(méi)有復(fù)雜的參數(shù)處理,只不過(guò)返回的值不是集合而是單一的值,具體用法類似SimpleQuery。
HqlBasedQuery是最為強(qiáng)大的Query類,支持跨庫(kù)/跨基類聯(lián)合查詢;可以使用HqlBasedQuery來(lái)實(shí)現(xiàn)選定屬性查詢,返回的結(jié)果為ArrayList,結(jié)構(gòu)形式與SQL查詢類似,可每行作為一個(gè)Object,而后按順序提取字段值,具體用法參考下例:
public static string FindMaxSnOfOuterDriver()
{
string hql = ""; HqlBasedQuery query;
hql = @"select max(dir.Driver_sn) from Driver dir where dir.Is_in = 'False' ";
query = new HqlBasedQuery(typeof(Driver), hql);
IList result= (IList)ActiveRecordBase.ExecuteQuery(query);
if (result == null || result.Count == 0)
return "10000";
else
else return result[0].ToString();
}
小結(jié)
根據(jù)以上的介紹,利用ActiveRecord數(shù)據(jù)庫(kù)訪問(wèn)中間件,極大的簡(jiǎn)化了數(shù)據(jù)庫(kù)操作,可以擴(kuò)展數(shù)據(jù)庫(kù)系統(tǒng)的應(yīng)用范圍。這種中間件不僅適應(yīng)于局域網(wǎng),更加適應(yīng)于未來(lái)的基于廣域網(wǎng)的應(yīng)用程序。ActiveRecord數(shù)據(jù)訪問(wèn)中間件不僅跨平臺(tái),而且使用方便,并且擴(kuò)展性高。上述例子是以微軟的SQL SERVER作為數(shù)據(jù)庫(kù)應(yīng)用,如要擴(kuò)展到Oracle或其他數(shù)據(jù)庫(kù)只需更新其相應(yīng)的.Net插件即可。Castle的ActiveRecord底層將NHibernate封裝了起來(lái),使用起來(lái)感覺(jué)比Nhibernate方便多了,不用再去生成一個(gè)個(gè)的映射文件,調(diào)試和維護(hù)起來(lái)都方便了很多。
經(jīng)過(guò)在物流倉(cāng)儲(chǔ)綜合支撐平臺(tái)中應(yīng)用數(shù)據(jù)訪問(wèn)中間件,程序的開(kāi)發(fā)周期大大縮短,程序的可維護(hù)性,以及可擴(kuò)展性得到了提高,在信息管理平臺(tái)中使用數(shù)據(jù)訪問(wèn)中間件將是一個(gè)有效的解決方案。