999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

NHibernate代碼生成器的設(shè)計(jì)與實(shí)現(xiàn)

2008-12-31 00:00:00蔣尚亭
電腦知識(shí)與技術(shù) 2008年31期

摘要:采用代碼生成技術(shù)能大幅提高軟件開發(fā)的質(zhì)量和生產(chǎn)率,降低軟件開發(fā)的風(fēng)險(xiǎn)。本文將介紹了基于C#的NHibernate代碼生成器的設(shè)計(jì)與實(shí)現(xiàn)過程,并分析了常見的代碼生成技術(shù),同時(shí)結(jié)合實(shí)例說明核心源代碼。

關(guān)鍵詞:代碼生成器;C#;NHibernate;XML

中圖分類號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2008)31-0908-04

Design and Implementation of NHibernate Code Generator

JIANG Shang-ting, LI Wei

(Computer Centor, Anhui Preofessional Scientifical College of News Publishment, Hefei 230601, China)

Abstract: Code technology can be used to generate a substantial increase in the quality of software development and productivity, reduce the risk of software development. This article based on the C# code generation NHibernate Design and Implementation of the process and analysis of the common code generation technology, combined with examples of the core source code.

Key words: code generator; C#; NHibernate; XML

NHibernate是一個(gè)面向.NET環(huán)境的對(duì)象/關(guān)系數(shù)據(jù)庫(kù)映射工具。NHibernate很好的實(shí)現(xiàn)了關(guān)系型數(shù)據(jù)庫(kù)到面向?qū)ο髮?shí)體的映射,并且提供數(shù)據(jù)查詢和獲取數(shù)據(jù)的方法,從而大幅度減少開發(fā)時(shí)人工使用SQL和ADO.NET處理數(shù)據(jù)的時(shí)間,提高了效率和安全性。但是在使用NHibernate之前需要手寫大量配置文件和POJO類,并且一旦有錯(cuò)誤就會(huì)導(dǎo)致整個(gè)程序的錯(cuò)誤,也就提高了整個(gè)項(xiàng)目的復(fù)雜性。那么,如何才能有效的去完成這項(xiàng)工作?本文將向大家介紹NHibernate的代碼生成器的設(shè)計(jì)與實(shí)現(xiàn),同時(shí)大家也可以參考實(shí)現(xiàn)其他功能的代碼生成器。

1 代碼生成器的實(shí)現(xiàn)原理

綜合大部分的代碼生成器,我們不難看出,絕大多數(shù)都采用了XML、XSLT技術(shù)。其主要原因在于首先XML的國(guó)際標(biāo)準(zhǔn)化,其次XML可以表示層次結(jié)構(gòu)有利于設(shè)計(jì)和實(shí)現(xiàn)。而XSLT是一種將XML文檔轉(zhuǎn)換為其他文本文檔的語言,它是建立在XML和XPath之上的國(guó)際標(biāo)準(zhǔn),功能強(qiáng)大。兩者結(jié)合可以很容易實(shí)現(xiàn)代碼生成功能。

考慮到NHibernate是ORM工具,而XML可以很容易的實(shí)現(xiàn)數(shù)據(jù)表的層次結(jié)構(gòu),同時(shí)C#語言中包含了實(shí)現(xiàn)對(duì)XML和XSLT的操作的類庫(kù)。所以本文也將采用XML、XSLT技術(shù)來實(shí)現(xiàn)NHibernate代碼生成器。基本的原理如圖1所示。

2 代碼生成器的設(shè)計(jì)原理

要實(shí)現(xiàn)將關(guān)系數(shù)據(jù)庫(kù)模型通過代碼生成器映射為所需要的代碼,首先要將關(guān)系數(shù)據(jù)庫(kù)模型轉(zhuǎn)換為代碼生成器可以讀取的文件, 然后代碼生成器從這些輸入文件中提取出模型中的信息并生成相應(yīng)的代碼。那么在這里我們使用的是XML文檔,這樣就必須將我們的關(guān)系型數(shù)據(jù)庫(kù)模型轉(zhuǎn)換為XML文檔。為了實(shí)現(xiàn)較好的通用性,本代碼生成器可以實(shí)現(xiàn)ACCESS、MSSQL、ORACLE這三個(gè)數(shù)據(jù)庫(kù)轉(zhuǎn)換功能。接著我們將使用XSLT作為模板,完成從XML到代碼的轉(zhuǎn)換過程。從而實(shí)現(xiàn)代碼生成器的基本功能。

2.1 數(shù)據(jù)庫(kù)模型到XML文檔的轉(zhuǎn)換

這里關(guān)鍵是獲取數(shù)據(jù)庫(kù)的基本信息,包括表、字段、索引、鍵等,這次都可以通過數(shù)據(jù)庫(kù)中的系統(tǒng)表獲得,下面給出三個(gè)數(shù)據(jù)中數(shù)據(jù)庫(kù)的基本信息獲取方法。

對(duì)于MSSQLServer,數(shù)據(jù)庫(kù)中有SysObjects和SysColumns這兩個(gè)系統(tǒng)表,我們可以查詢系統(tǒng)表來獲得所有的表名稱和字段名稱以及格式,還有一個(gè)sp_helpindex 的系統(tǒng)預(yù)定義存儲(chǔ)過程來獲得指定表的字段索引信息。

對(duì)于Oracle,數(shù)據(jù)庫(kù)有一個(gè)名為Col的系統(tǒng)預(yù)定義視圖,我們可以查詢這個(gè)視圖獲得所有的表名和字段定義信息。還有一個(gè) user_ind_columns的系統(tǒng)預(yù)定義視圖,我們可以關(guān)鍵字段信息。

對(duì)于Access2000數(shù)據(jù)庫(kù),沒有這些系統(tǒng)表,因此我們使用。NET框架中的OleDB的數(shù)據(jù)連接對(duì)象的GetOleDbSchemaTable函數(shù)來獲得數(shù)據(jù)庫(kù)表和字段定義信息。

現(xiàn)在我們通過上面的方法可以獲取數(shù)據(jù)庫(kù)的信息了,后面我們要做的就是將它生成指定的XML文檔了。GetTableXML(string tableName)方法實(shí)現(xiàn)了讀取數(shù)據(jù)庫(kù)信息并生成XML字符串的功能。

/// <summary>

/// 實(shí)現(xiàn)對(duì)單個(gè)表的轉(zhuǎn)換為XML文檔的函數(shù)

/// </summary>

/// <param name=\"tableName\">表名</param>

/// <returns>XML字符串</returns>

public string getSQLTableXML(string tableName)

{string fieldType = \"\";

string strSQL = 1; //用戶查詢單個(gè)表中的字段屬性

strSQL = @\"select sysobjects.name ,syscolumns.name,systypes.name ,syscolumns.length , syscolumns.is1able ,sysobjects.type from syscolumns, sysobjects, systypes where syscolumns.id=sysobjects.id and syscolumns.xusertype=systypes.xusertype and (sysobjects.type='U' or sysobjects.type='V' ) and systypes.name <>'_default_' and systypes.name<>'sysname'and sysobjects.name ='\" + tableName + \"' order by sysobjects.name, syscolumns.name\";

DataView mydv = SQLHelper.ExecuteDataView(strSQL);

StringBuilder sb = new StringBuilder(); //構(gòu)建XML字符串

if (mydv.Count > 0)

{sb.Append(\"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\");

sb.Append(\"<TableInfo xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\");

sb.Append(\"using System;\");

sb.Append(\"<Schema>\");

sb.Append(\"<SchemaName>test</SchemaName>\");

sb.Append(\"<Table>\");

sb.Append(\"<TableName>\" + mydv[0][0].ToString() + \"</TableName>\");

sb.Append(\"<Fields>\");

for (int i = 0; i < mydv.Count; i++)

{sb.Append(\"<Field>\");

sb.Append(\"<Name>\" + mydv[i][1].ToString() + \"</Name>\");

fieldType = this.getType(mydv[i][2].ToString());

sb.Append(\"<FieldType>\" + fieldType + \" </FieldType>\");

sb.Append(\"<FieldLength>\" + mydv[i][2].ToString() + \" </FieldLength>\");

sb.Append(\"</Field>\");

}

sb.Append(\"</Fields>\");

sb.Append(\"</Table>\");

sb.Append(\"</Schema>\");

sb.Append(\"</TableInfo>\");

}return sb.ToString();

}

通過上面的代碼我們可以將數(shù)據(jù)庫(kù)中的一個(gè)表轉(zhuǎn)換為一個(gè)XML字符串。生成后的XML文件格式為:

<?xml version=\"1.0\" encoding=\"utf-8\"?>

<TableInfo xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">

<Schema>

<SchemaName>test</SchemaName> <!--程序集的名稱-->

<Table>

<TableName>t_sys_role</TableName><!--表名的名稱-->

<Fields>

<Field>

<Name>role_id</Name><!--字段的名稱-->

<FieldType>int</FieldType><!--字段的類型-->

<FieldType>int</FieldType><!--字段的類型-->

<FieldLength>4</FieldLength><!--字段的長(zhǎng)度-->

</Field>

……

</Fields>

</Table>

</Schema>

</TableInfo>

這樣我們就完成了數(shù)據(jù)庫(kù)模型向XML文檔的轉(zhuǎn)換。這里注意轉(zhuǎn)換中要將數(shù)據(jù)庫(kù)數(shù)據(jù)類型轉(zhuǎn)換為C#語言或其他語言的數(shù)據(jù)類型。如下所示:

private string getType(string dbtype)

{switch (dbtype)

{case \"varchar\":

……

return \"string\";

case \"date\":

……

return \"DateTime\";

……}

2.2 制定生成代碼的模板

XSLT是一種將XML文檔轉(zhuǎn)換為其他文本文檔的語言,它是建立在XML和XPath之上的國(guó)際標(biāo)準(zhǔn),功能強(qiáng)大。我們這里使用XSLT作為模板,可以方便的將XML文檔轉(zhuǎn)換為具體的代碼。下面是一個(gè)簡(jiǎn)單的模板用于生成POJO類:

<?xml version=\"1.0\" encoding=\"utf-8\" ?>

<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">

<xsl:output method='text' />

<xsl:template match=\"/*\">

using System;

namespace <xsl:apply-templates select=\"http://SchemaName\" />

{public class <xsl:apply-templates select=\"http://TableName\" />

{<xsl:for-each select=\"Schema/Table/Fields/Field\"><xsl:value-of select=\"FieldType\" /> _<xsl:value-of select=\"Name\" /> ;

</xsl:for-each>

<xsl:for-each select=\"Schema/Table/Fields/Field\">

public <xsl:value-of select=\"FieldType\" /> <xsl:value-of select=\"Name\" />

{get{return _<xsl:value-of select=\"Name\" />;}

set{_<xsl:value-of select=\"Name\" /> = Value;}

}</xsl:for-each>

}</xsl:template>

</xsl:stylesheet>

當(dāng)然模板你可以自己定義,然后在程序中動(dòng)態(tài)的加載,從而實(shí)現(xiàn)多語言(VB.NET、JAVA等),并且可以設(shè)計(jì)自己的專用模板來生成自己想要的代碼。

2.3 將XML轉(zhuǎn)換為代碼

現(xiàn)在我們已經(jīng)完成了XML和XSLT這兩個(gè)文檔了,下面就是用.NET平臺(tái)下的System.Xml.Xsl. XslCompiledTransform類來實(shí)現(xiàn)生成代碼了。

xml = gc.getTableXML(\"t_sys_role\");//獲取表的基本信息存儲(chǔ)到XML文件中

System.Xml.Xsl. XslCompiledTransform transform = new System.Xml.Xsl. XslCompiledTransform ();

transform.Load(\"_HN_POJO.xslt\"); //加載POJO的XSLT文件

transform.Transform(\"role.xml\",\"role.cs\"); //使用Transform方法實(shí)現(xiàn)代碼的生成,生成文件為role.cs

//復(fù)制生成文件到指定的目錄下

System.IO.File.Copy(projectPath + @\"\\ role.cs\", txtProjectFolder.Text + @\"\\mapping\\\", true);

transform.Load(\"_HN_HBM.xslt\");//加載HBM的XSLT文件

transform.Transform(“role.xml”,”role.hbm.xml”);

System.IO.File.Copy(projectPath + @\"\\ role.hbm.xml \", txtProjectFolder.Text + @\"\\mapping\\\", true);

通過以上的代碼九完成了將role.xml轉(zhuǎn)換為role.cs的過程了。生成后的代碼效果如下:

using System;

namespace test

{ public class t_sys_role

{ int _role_id ; …

public int _role_id

{ get{return _role_id;}

set{_role_id = Value;}

}

……}

同時(shí)也生成了需要的hbm.xml文件。

3 程序構(gòu)架

程序的整個(gè)結(jié)構(gòu)如圖1所示。

其中的代碼核心部分在KitCore類庫(kù)中:

DataBaseInfo.cs、FieldInfo.cs、TableInfo.cs分別用于表述數(shù)據(jù)庫(kù)信息、字段信息、表信息。

SQLHelper.cs主要實(shí)現(xiàn)操作SQL數(shù)據(jù)庫(kù)的幫助類。(可以根據(jù)需要增加相關(guān)的數(shù)據(jù)庫(kù)操作)

GenerateCore.cs主要實(shí)現(xiàn)代碼生成的類。

NHibernate Kit應(yīng)用程序是主要完成界面的功能:MainForm.cs是主界面,AboutBox.cs是軟件信息,KitHelper.cs是一些幫助類。界面請(qǐng)參考圖2(用于數(shù)據(jù)庫(kù)的連接)、圖3(選擇生成的數(shù)據(jù)表)、圖4(設(shè)置相關(guān)的參數(shù))、圖5(生成代碼)、圖6(設(shè)置用于生成的模板)。

下面給出部分主要的源代碼:

3.1 獲取本地的SQL服務(wù)器名(圖2中的刷新按鈕)

private void btnRefresh_Click(object sender, EventArgs e)

{try

{this.Cursor = Cursors.WaitCursor; //修改鼠標(biāo)的狀態(tài)為沙漏狀

//獲取本地計(jì)算機(jī)SQL服務(wù)器名

cmbServerNames.DataSource = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources();

cmbServerNames.DisplayMember = \"ServerName\";

}

……}

3.2 獲取指定服務(wù)器下的數(shù)據(jù)庫(kù)列表(圖2中的下拉框)

private void cmbDatabaseNames_DropDown(object sender, EventArgs e)

{try

{this.Cursor = Cursors.WaitCursor;

//通過SQLHelper.cs中的getData Set方法返回?cái)?shù)據(jù)源,其中select name, dbid from sysdatabases用于返回服務(wù)器中的所有數(shù)據(jù)庫(kù)。

cmbDatabaseNames.DataSource =SQLHelper.getDataSet (\"select name, dbid from sysdatabases\");

cmbDatabaseNames.DisplayMember = \"name\";

cmbDatabaseNames.ValueMember = \"dbid\";

}

……}

3.2 獲取指定數(shù)據(jù)庫(kù)下的數(shù)據(jù)表列表(圖2中的下一步)

private void btnNext_Click(object sender, EventArgs e)

{……

this.Cursor = Cursors.WaitCursor;

SetConnectionString();

DataTable dt = dataClass.ExecuteReader(\"SELECT [TableName] = so.name, [ID] = so.id FROM sysobjects so WHERE OBJECTPROPERTY(so.id, 'IsMsShipped') = 0 AND so.xtype = 'U'\");

chklistTables.Items.Clear();

foreach (DataRow dr in dt.Rows)

{chklistTables.Items.Add(dr[\"TableName\"]);}

……}

3.3 生成代碼按鈕的代碼(圖5中的三角形按鈕)

private void toolStripButton1_Click(object sender, EventArgs e)

{ //調(diào)用GenerateCore.cs中的Generate方法來生成代碼。絕大部分代碼已經(jīng)在設(shè)計(jì)原理中給出了,這里不在重復(fù)給出了

System.Threading.Thread t = new System.Threading.Thread((new System.Threading.ThreadStart(gc.Generate)));

t.Start();}

圖3、圖4、圖6主要是一些參數(shù)的設(shè)置,其代碼部分比較簡(jiǎn)單不一一列出了。

4 結(jié)束語

本文主要討論了通過XML、XSLT技術(shù)來設(shè)計(jì)NHibernate代碼生成器,使用XML來描述數(shù)據(jù)庫(kù)結(jié)構(gòu)而XSLT來完成模板功能,最后通過C#語言完成代碼的生成。目前,代碼生成技術(shù)已經(jīng)廣泛的應(yīng)用到實(shí)際的項(xiàng)目開發(fā)之中,大量的單位和個(gè)人都開進(jìn)入到這個(gè)方面。通過設(shè)計(jì)模型驅(qū)動(dòng)編碼的思想已經(jīng)逐步開始實(shí)現(xiàn)并應(yīng)用到實(shí)際項(xiàng)目之中。

參考文獻(xiàn):

[1] 陳翔, 王學(xué)斌, 吳泉源. 代碼生成技術(shù)在MDA中的實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用研究,2006(1):147.

[2] 范秋生. XML的代碼生成器的設(shè)計(jì)與實(shí)現(xiàn)[J].長(zhǎng)江大學(xué)學(xué)報(bào)(自然科學(xué)版),2008,5(1):211.

[3] 王忠杰,戰(zhàn)德臣,徐曉飛. 基于對(duì)象關(guān)系模型的企業(yè)應(yīng)用軟件代碼生成器[J].計(jì)算機(jī)集成制造系統(tǒng),2007(5):1021.

[4] 袁永福. C#發(fā)現(xiàn)之旅[EB/OL]. [2008-09-08].http://www.cnblogs.com/xdesigner/.

主站蜘蛛池模板: 91精品国产福利| 日韩中文无码av超清| 999精品色在线观看| 亚洲美女视频一区| 国产主播喷水| 亚洲美女高潮久久久久久久| 国产在线精品香蕉麻豆| 夜夜拍夜夜爽| 亚洲成aⅴ人在线观看| 日韩毛片在线播放| 国产精品免费p区| h视频在线播放| 久久久久久久97| 欧美高清三区| 国产内射一区亚洲| 国产精品视频观看裸模| 久久无码高潮喷水| 日本在线国产| 五月婷婷激情四射| 亚欧乱色视频网站大全| 亚洲AV无码乱码在线观看代蜜桃 | 一级黄色网站在线免费看| 国产一区二区三区夜色| 婷婷六月综合| 欧美69视频在线| 亚洲成人播放| 又猛又黄又爽无遮挡的视频网站| 国产精品va免费视频| 午夜老司机永久免费看片| 天天躁夜夜躁狠狠躁躁88| 99久久国产综合精品2023| 无码人妻免费| 国产区在线看| 国产精品第一区在线观看| 老色鬼久久亚洲AV综合| 亚洲人免费视频| 日本国产精品一区久久久| 国产激爽爽爽大片在线观看| 免费可以看的无遮挡av无码| 亚洲国产成人无码AV在线影院L| 国产区91| 永久免费精品视频| 国产一国产一有一级毛片视频| 亚洲第一黄片大全| 亚洲第一页在线观看| 亚洲国产精品成人久久综合影院| 热99精品视频| 久久久久久高潮白浆| 四虎成人精品| 国产迷奸在线看| 国产精品吹潮在线观看中文| 爆乳熟妇一区二区三区| 中文字幕在线观看日本| 99精品视频播放| 国产无码在线调教| 亚洲一区二区三区国产精品 | 国产成人一区| 国产H片无码不卡在线视频| 欧美日韩中文国产| 亚洲精品午夜天堂网页| 一级爆乳无码av| 国产一区亚洲一区| 国产欧美另类| 日韩欧美国产成人| 高潮爽到爆的喷水女主播视频 | 国产精品久久久久婷婷五月| 四虎亚洲精品| A级毛片无码久久精品免费| 亚洲综合色区在线播放2019| 国产欧美日韩视频一区二区三区| www.youjizz.com久久| 欧美a网站| 91蝌蚪视频在线观看| 国产91丝袜在线播放动漫| 久久综合色播五月男人的天堂| 亚洲成人福利网站| 在线欧美a| 午夜视频www| 欧美人与牲动交a欧美精品| 欧美啪啪视频免码| 98精品全国免费观看视频| 国产无码在线调教|