日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

發布時間:2023/12/15 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Nhibernate+SQLite 入门实例指南二 类的继承、多态关系 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?昨天忘記向源代碼下載了,現在補上第一章的代碼:http://files.cnblogs.com/9527/QuickStart1.rar

實例二、類的繼承、多態關系

在我們實際設計過程中,經常碰到類的繼承關系,比如一個電子產品商店,同時銷售手機和MP3,所以在設計系統的時候我們把手機和MP3的共性如品牌、名稱等抽象為一個類,而把它們的特性比如MP3有內存容量,手機有號碼等,我們以不同的子類來體現。如下圖:

在實際數據庫的時候,最簡單的就是每個子類擁有一個獨立的表分別對應Mp3player和MobilePhone

由于MobilePhone和Mp3Player都是繼承electronic,所以他們都Id,Name,Brand等屬性,了我們分別為兩個表編寫映射文件:

MobilePhone.hbm.xml

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

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.0">?

<class?name="QuickStart2.Data.MobilePhone,?QuickStart2.Data"?table="t_mobilephone"?>?

<id?name="Id"?column="id"?type="Int32">?

<generator?class="identity"?/>?

</id>?

<property?name="Name"?type="String(100)"?column="name"?/>?

<property?name="Brand"?type="String(20)"?column="brand"?/>?

<property?name="Phonenumber"?type="String(13)"?column="phonenumber"?/>?

</class>?

</hibernate-mapping>?

Mp3Player.hbm.xml?

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

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.0">?

<class?name="QuickStart2.Data.Mp3Player,?QuickStart2.Data"?table="t_mp3player"?>?

<id?name="Id"?column="id"?type="Int32">?

<generator?class="identity"?/>?

</id>?

<property?name="Name"?type="String(100)"?column="name"?/>?

<property?name="Brand"?type="String(20)"?column="brand"?/>?

<property?name="Mensize"?type="Int32"?column="mensize"?/>?

</class>?

</hibernate-mapping>?


可以看到這兩個映射和普通的映射文件沒有什么不同。我們編寫了一個段測試代碼:

?

ISession?session=null;?

ArrayList?list
=null;?

try{?

session
=SessionFactory.OpenSession();?

list
=(ArrayList)session.CreateCriteria(typeof(electronic)).List();?

}
?

catch(Exception?e)?{?

System.Console.WriteLine(e.Message);?

System.Console.ReadLine();?

}
?

finally{?

session.Close();?

}
?

foreach(electronic?el?in?list)?{?

System.Console.WriteLine(
"名稱:o"+el.Name);?

}
?

運行結果如下圖所示:

我們看到NHibernate更據electronic自動找到它的兩個子類Mp3Player和MobilePhone,生存兩鐵絲SQL語句分別查詢兩個表,下面輸出的是,查詢出來的結果。

為什么會這樣子,在NHibernate中是用多態(polymorphism)來進行描述兩個繼承于同一父類的子類情況,在映射文件的Class節點中也有一個polymorphism的屬性用來設定是隱式還是顯式的使用查詢多態,為什么我們的映射類中沒有出現這個屬性的設定呢,polymorphism?=?implicit是默認的。所以我們如果進行的是隱式的查詢就可以不用進行設定。以下是摘自博客園renrenqq?翻譯的NHibernate中文文檔中對polymorphism的解釋:

Implicit (隱式)的多態是指,如果查詢中給出的是任何超類、該類實現的接口或者該類的名字,都會返回這個類的實例;如果查詢中給出的是子類的名字,則會返回子類的實例。Explicit?(顯式)的多態是指,只有在查詢中給出的明確是該類的名字時才會返回這個類的實例;同時只有當在這個?<class>?的定義中作為?<subclass>?或者?<joined-subclass>?出現的子類,才會可能返回。?大多數情況下,默認的polymorphism="implicit"都是合適的。?顯式的多態在有兩個不同的類映射到同一個表的時候很有用。(允許一個“輕型”的類,只包含部分表字段)。

通過這樣的方式我們雖然也實現了我們想要的結果,但是對經驗豐富的設計人員來說,這樣的設計是并不合理的,一旦父類分生了變動,數據庫里兩個表都必須修改,而且從性能角度上來說也并不怎么理想。

所以,更據經驗我們一般會吧兩個表相同的字段合并成一個表,另建兩個新表,只包含Mp3Player和MobilePhone的特有的屬性。經過修改我們的數據庫結構如下圖如示:

可以看到主表于子表之間通過外鍵向連。

數據庫修改以后,我們要重新設計映射文件,讓它正確的映射到關系型數據庫。

Electronic.hbm.xml

?

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

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.0">?

<class?name="QuickStart2.Data.electronic,?QuickStart2.Data"?table="t_electronic">?

<id?name="Id"?column="id"?type="Int32">?

<generator?class="identity"?/>?

</id>?

<property?name="Name"?type="String(100)"?column="name"?/>?

<property?name="Brand"?type="String(20)"?column="brand"?/>?

<joined-subclass?name="QuickStart2.Data.MobilePhone,QuickStart2.Data"?table="t_mobile">?

<key?column="id"?/>?

<property?name="Phonenumber"?type="String(13)"?column="phonenumber"?/>?

</joined-subclass>?

<joined-subclass?name="QuickStart2.Data.Mp3Player,QuickStart2.Data"?table="t_mp3">?

<key?column="id"?/>?

<property?name="Mensize"?type="Int32"?column="mensize"?/>?

</joined-subclass>?

</class>?

</hibernate-mapping>?

通過映射文件我們可以看到,我們為主類建立了映射,兩個子類在<joined-subclass>節點下進行了配置。

我們現編寫一段數據插入代碼來看看,NHibernate是怎么進行數據插入的

?

public?static?void?SaveMobilephone()?

{?

ISession?session
=null;?

ITransaction?t
=null;?

try?

{?

session
=SessionFactory.OpenSession();?

t
=session.BeginTransaction();?

MobilePhone?mp
=new?MobilePhone();?

mp.Name
="575";?

mp.Brand
="Dopod";?

mp.Phonenumber
="13151921698";?

Mp3Player?mp3
=new?Mp3Player();?

mp3.Name
="SB200";?

mp3.Brand
="小霸王";?

mp3.Mensize
=513;?

session.Save(mp3);?

session.Save(mp);?

session.Flush();?

t.Commit();?

}
?

catch(HibernateException?e)?

{?

System.Console.Write(e.Message.ToString());?

if(t!=null)?

{?

try?

{?

t.Rollback();?

}
?

catch(HibernateException?e1)?

{?

System.Console.Write(e1.Message.ToString());?

}
?

}
?

}
?

finally?

{?

session.Close();?

}
?

System.Console.ReadLine();?

}
?

編譯運行如上代碼,在返回中我們看到如下結果

根據圖片,我們可以看到,和前一次不同,NHibernate分四次,分別對主表和子表進行插入。

在運行我們在上一節中的查詢代碼,其結果是

我們可以看到,NHibernate用了一條組合查詢,一次性就把三個表所有數據查詢了出來。

從上面的例子我們可以看到,這樣的設計,雖然從設計的邏輯上來說更加清晰明了,符合我們的設計習慣,但是多表操作帶來的性能的消耗來是相當的可觀,因此,如果我們的系統對性能上有相當的要求,我們就要考慮第三種方式。

我們把數據設計成不僅包含用父類的共同屬性,也同是用不同的字段來表示兩種產品的不同特性,這樣如何來區別兩個類呢,我們在數據庫中加入一個”category”的字段來區別兩種產品。

代碼方面我們需要修改的也只有數據庫的映射文件,把新映射文件修改成如下:

?

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

<hibernate-mapping?xmlns="urn:nhibernate-mapping-2.0">?

<class?name="QuickStart2.Data.electronic,?QuickStart2.Data"?table="t_elec">?

<id?name="Id"?column="id"?type="Int32">?

<generator?class="identity"?/>?

</id>?

<discriminator?column="category"?type="String(10)"?/>?

<property?name="Name"?type="String(100)"?column="name"?/>?

<property?name="Brand"?type="String(20)"?column="brand"?/>?

<subclass?name="QuickStart2.Data.MobilePhone,QuickStart2.Data"?discriminator-value="1"?>?

<property?name="Phonenumber"?type="String(13)"?column="phonenumber"?/>?

</subclass>?

<subclass?name="QuickStart2.Data.Mp3Player,QuickStart2.Data"?discriminator-value="2"?>?

<property?name="Mensize"?type="Int32"?column="mensize"?/>?

</subclass>?

</class>?

</hibernate-mapping>?

于前一節中的映射文件不一樣的是,我們在映射文件中加入了一個識別器(discriminator),用來指定數據庫中哪個字段是用來做為標識的。

在定義的子類的時候,也不能用joined-subclass 而要改成subclass joined-subclass不能支持discriminator-value屬性,discriminator-value就是用來區分獨立的子類當我們完成數據庫的插入操作后(具體代碼可以用上一節所提供的代碼,由于代碼完全相同,所以不再次提供了)我們可以看到,NHibernate只用了兩次插入動作就完成了對數據的插入。

我們再運行查詢的代碼也可以用一條簡單的SQL語句來完成操作,大家也可以試著用

list=(ArrayList)session.CreateQuery("from Mp3player").List();

list=(ArrayList)session.CreateQuery("from MobilePhone").List();

進行查詢,在NHibernate生的結果如下圖:

可以看到,NHibernate在讀取數據的時候會自動更據標識讀取Mp3Player或MobilePhone的內容。

但是這種方法也有它的硬傷,如果子類的特性太多,哪數據庫的可讀性就大打折扣了,甚至可以讓人抓狂,對于系統的后期維護升級非常的不利。

因此、三種方法各有各的優點也各有缺點,我們要在設計的過程中更據實際情況進于權衡,然后才確定采用何種方式。
第二章代碼下載:http://files.cnblogs.com/9527/QuickStart2.rar






? ? 本文轉自無心之柳.NET博客園博客,原文鏈接:http://www.cnblogs.com/9527/archive/2006/09/24/513505.html,如需轉載請自行聯系原作者



創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的Nhibernate+SQLite 入门实例指南二 类的继承、多态关系的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。