【翻譯】How-To: Using the N* Stack, part 3

原文地址:http://jasondentler.com/blog/2009/08/how-to-using-the-n-stack-part-3/?

Java – 一種代碼松散的XML

在我們學習 Fluent NHibernate 之前, 應該先了解下老式的 NHibernate 映射文件應該是怎樣寫的。 在一個典型的 NHibernate 配置中,你會有很多類似這樣的映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"><class name="NStackExample.Address, NStackExample.Core" table="Address"><composite-id><key-many-to-one name="Person" class="NStackExample.Person, NStackExample.Core" column="ID" /><key-property name="Type" type="Int32" /></composite-id><property name="City" type="String" length="255" /><property name="Lines" type="String" length="255" /><property name="State" type="String" length="2" /><property name="Zip" type="String" length="10" /></class>
</hibernate-mapping>

你必須為每一個實體類配置一個這樣的映射文件,這種做法是從 Java 的 Hibernate 中遺留下來的。在我看來,這么做是非常痛苦的,不過幸運的是,有一個好辦法來解決這個問題。

更好的選擇: Fluent Mappings

有了 Fluent NHibernate ,上面的映射文件就可以用下面這個類來代替:

using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class AddressMapping : ClassMap<Address>{public AddressMapping(){UseCompositeId().WithKeyReference(x => x.Person).WithKeyProperty(x => x.Type);Map(x => x.Lines).WithLengthOf(255);Map(x => x.City).WithLengthOf(255);Map(x => x.State).WithLengthOf(2);Map(x => x.Zip).WithLengthOf(5);}}
}

看起來這個類可能比之前的映射文件還要復雜,但是因為有智能感知,我們能輕而易舉的完成,并且我們不用擔心魔字符串(magic strings)的問題。當你使用重構工具來改變屬性名稱的時候,你的映射文件也會同步改變。

現在大家都知道基本的概念了吧,那么讓我們繼續。

Where?

因為數據庫連接、 NHibernate 配置、實體類映射和 DAO 的實現只是我們選擇的ORM的執行細節,所以應該把他們放到一個單獨的程序集中。

  1. 創建一個新的類庫項目,名字叫做:NStackExample.Data 。
  2. 添加新項目的引用,將 Core 項目,NHibernate.dll 和 FluentNHibernate.dll 添加進去。
  3. 為了以后我們能輕松的檢索一些應用程序的設置,將System.Configuration.dll 也添加進去。
  4. 此外,在我們的 Web 項目中也需要將新建的項目添加到引用當中。

下面讓我們來完成我們的映射文件。

using NStackExample;
using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class CourseMapping : ClassMap<Course> {public CourseMapping(){Id(x => x.ID).GeneratedBy.GuidComb();Map(x => x.CourseNumber).Not.Nullable().WithLengthOf(4).UniqueKey("CourseNaturalKey");Map(x => x.Subject).Not.Nullable().WithLengthOf(4).UniqueKey("CourseNaturalKey");Map(x => x.Title).Not.Nullable().WithLengthOf(255);Map(x => x.Description).Not.Nullable().WithLengthOf(1024);Map(x => x.Hours).Not.Nullable();HasMany(x => x.Sections).AsSet().WithForeignKeyConstraintName("CourseSections");}}
}

上面的代碼非常容易理解,最后得到的就是我們需要的映射文件。

我們的映射類繼承自 ClassMap<Course> ,ClassMap 類是 Fluent NHibernate 搜索查找映射時的具體類型。在這里,這個類提供了 Course 實體類的映射。在構造函數中,我們定義了每個屬性的具體映射。

  • 將 Id 設置成持久化對象標示符(POID),基本上這就是數據表的主鍵。對于有多個屬性的主鍵,請參照我們上面 AddressMapping 示例中的 UseCompositeId 。我不建議使用多重主鍵,并且據我所知,Fluent NHibernate 也不支持多重主鍵。
  • GeneratedBy 是用來指定 POID 生成策略。在這里我們使用的是 GuidComb 。使用 GUID 做主鍵有非常多的好處,具體的內容大家可以參考 Davy Brion在NHForge博客上發表的隨筆。
  • Map 只是將屬性映射到數據庫的列上。如果有需要的話,你可以指定 Not.Nullable 和 WithLengthOf 。
  • UniqueKey 指定了列的唯一索引。如果你對多個列指定了相同的名稱,那么這些列都會變為這個唯一索引的一部分。在這個示例中,我們強制要求我們的自然鍵是唯一的。每個 subject 和 course number 都必須是唯一的。
  • HasMany 是定義了一個一對多的關系,你可以指定集合的確切行為。在這里有 Set 和 Bag 兩個選項。
    • AsSet 不允許重復的項目
    • AsBag 允許重復的項目

默認情況下,所有關系都是延遲加載的。就是說當你從數據庫中獲取到了 course ,和其相關聯的 sections 并不是馬上獲取出來,而是直到當你訪問該屬性的時候才會被加載進來,如果你從未訪問過該屬性的話,那么它永遠都不會被加載,這樣可以大大的提高性能。這些功能都是用代理來實現的。

下面容我們來映射 sections:

using NStackExample;
using FluentNHibernate.Mapping;namespace NStackExample.Data
{public class SectionMapping : ClassMap<Section> {public SectionMapping(){Id(x => x.ID).GeneratedBy.GuidComb();Map(x => x.FacultyName).WithLengthOf(255);Map(x => x.RoomNumber).WithLengthOf(10);Map(x => x.SectionNumber).WithLengthOf(4).Not.Nullable().UniqueKey("SectionNaturalKey");References(x => x.Course).Not.Nullable().UniqueKey("SectionNaturalKey");References(x => x.Term).Not.Nullable().UniqueKey("SectionNaturalKey");HasMany(x => x.StudentSections).AsSet().WithForeignKeyConstraintName("SectionStudentSections");}}
}

在這里引入了多對一關系的映射,可以把它看成一對多關系的另一邊。 本示例中就是從孩子 section 到它的父親 course 的關系。

練習:完成所有實體類的映射。

到這里或許你會在想這個系列是不是會很長很長呢?到現在我們甚至連數據庫都還沒有開始建立。不用擔心,這些事 NHibernate 會幫我們做的。

8小時 or 8分鐘?

在我沒有使用 NHibernate 之前,我至少需要一天的時間來建立數據庫。這讓我很郁悶,估計大家也一樣很不喜歡浪費這么多時間去建立數據庫。不過,這樣的事情將在今天結束。

聲明: 如果你嘗試使用現有的舊版數據庫和數據庫架構,沒有什么調整的機會或者很渺茫,Fabio Maulo 的這篇隨筆 將告訴你如何選擇。

首先,讓我們配置 NHibernate 。在 Fluent NHibernate Wiki 上 有一篇非常好的文章 介紹了應該如何配置。

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using System.IO;
using System.Configuration;namespace NStackExample.Data
{public class Configuration{private ISessionFactory m_Factory;private string m_SchemaPath;public Configuration Configure(){m_SchemaPath = ConfigurationManager.AppSettings["NStackExample.Data.Configuration.SchemaPath"];m_Factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2005.ConnectionString(x => x.FromConnectionStringWithKey("NStackExample.Data.Configuration.Db"))).Mappings(x => x.FluentMappings.AddFromAssemblyOf<CourseMapping>().ExportTo(m_SchemaPath)).ExposeConfiguration(BuildSchema).BuildSessionFactory();return this;}private void BuildSchema(NHibernate.Cfg.Configuration cfg){SchemaExport SchemaExporter = new SchemaExport(cfg);SchemaExporter.SetOutputFile(Path.Combine(m_SchemaPath, "schema.sql"));SchemaExporter.Create(true, false);}public ISession OpenSession(){if (m_Factory == null) Configure();return m_Factory.OpenSession();}}
}

配置分為兩個部分:數據庫和映射。在本示例中,數據庫使用的是 SQL 2005,連接字符串是從 Web.config 文件中讀取的。 所有的映射部分都是從
fluent 中讀取的,沒有自動映射。注意,我們出口的映射是在 web.config 文件的 appsettings 節中指定的一個目錄,這會將我們 fluent 的映射分別轉換成 hbm.xml文件。這么做是為了方便我們映射部分的調試,尤其是在需要 NHibernate 在線幫助的時候。

這里有個附加項,我們使用 ExposeConfiguration 方法調用 BuildSchema 函數來完成對 NHibernate 的配置。

在 BuildSchema 中,我們使用NHibernate中非常好的一個工具:schema export 。這個工具將會幫助我們創建數據庫。構造函數接受兩個布爾值的參數。第一個參數指定是否輸出 DDL 文件 -- 一個包含所有表、鍵、索引和關系的數據庫腳本。 第二個參數指定了是否將腳本應用到指定的數據庫上。

非常簡單吧。

兩個警告:

  • 執行腳本將刪除并創建和你的 Model 相關的每一個表,這對已有的環境可能是極具破壞性的操作。
  • 腳本一般不會帶有“use [databasename]”語句,所以你如果不小心執行了,可能會建立到 master 數據庫中,在執行腳本的時候請注意選擇數據庫。

在下篇教程當中,我們將介紹如何對你的映射進行測試,包括讀取、查詢和寫入數據庫。

轉載于:https://www.cnblogs.com/LeoXing/archive/2009/10/05/how-to-using-the-n-stack-part-3.html

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

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

相關文章

你可能需要的網易前端三輪面經

關注若川視野, 回復"pdf" 領取資料&#xff0c;回復"加群"&#xff0c;可加群長期交流前言最近一個星期面了幾家公司&#xff0c;最后收獲了心儀的網易有道offer&#xff0c;于是推掉了其他的面試&#xff0c;至于一些其他大廠&#xff0c;并沒有投簡歷&am…

PHP yii 框架源碼閱讀(一)

轉載鏈接&#xff1a;http://www.th7.cn/Program/php/2012/04/03/67983.shtml 目錄文件 |- framework 框架核心庫 |-|- base 底層類庫文件夾&#xff0c;包 含CApplication(應用類&#xff0c;負責全局的用戶請求處理&#xff0c;它管理的應用組件集&#xff0c;將提供特定功…

復習.net/c#時的小文章之萬年草稿版 (全是基礎概念,請懂的人繞行)

必讀文&#xff1a;61條面向對象設計的經驗原則&#xff08;體會篇&#xff09; C#知識點集合 (面試必備)一、顯式(explicit)轉換和隱式(implicit)轉換的一般概念int i 100; Response.Write(i); // 這就是隱式 Response.Write(i.ToString()); // 這就是顯式 一般來講&#xff…

timertask run函數未執行_圖執行模式下的 TensorFlow 2

文 / 李錫涵&#xff0c;Google Developers Expert本文節選自《簡單粗暴 TensorFlow 2.0》盡管 TensorFlow 2 建議以即時執行模式(Eager Execution)作為主要執行模式&#xff0c;然而&#xff0c;圖執行模式(Graph Execution)作為 TensorFlow 2 之前的主要執行模式&#xff0c…

AJAX自學筆記01

從今天開始正式系統學習asp.net ajax了。XMLHttpRequest對象屬性&#xff1a;Number readyState (返回值4表示完成)Function onreadystatechange (執行回調函數)string responseText &#xff08;返回字符串型&#xff09;XMLDocument responseXML&#xff08;返回XML型&#x…

如何從 0 到 1 打造團隊 PC/H5 構建工具

關注若川視野, 回復"pdf" 領取資料&#xff0c;回復"加群"&#xff0c;可加群長期交流學習一、前言 大家好&#xff0c;我叫鰻魚&#xff0c;這次分享的主題是如何從 0 到 1 打造適合自己的構建部署方案。image.png先例行的自我介紹&#xff0c;大概 14 年…

PHP yii 框架源碼閱讀(二) - 整體執行流程分析

轉載鏈接&#xff1a;http://tech.ddvip.com/2013-11/1384432766205970.html 一 程序入口 <?php// change the following paths if necessary $yiidirname(__FILE__)./http://www.cnblogs.com/framework/yii.php; $configdirname(__FILE__)./protected/config/main.php;/…

HTTP狀態碼大全

完整的 HTTP 1.1規范說明書來自于RFC 2616&#xff0c;你可以在http://www.talentdigger.cn/home/link.php?urld3d3LnJmYy1lZGl0b3Iub3JnLw%3D%3D在線查閱。HTTP 1.1的狀態碼被標記為新特性&#xff0c;因為許多瀏覽器只支持 HTTP 1.0。你應只把狀態碼發送給支持 HTTP 1.1的客…

testng接口自動化測試_Java+Maven+TestNG接口(API)自動化測試教程(10) 使用 Jenkins 構建自動化測試持續集成...

現在代碼可以運行了&#xff0c;但是每次運行都需要我們手工去執行&#xff0c;并且測試報告也只能在執行測試的電腦上才能看到&#xff0c;我們希望能夠定時自動執行測試&#xff0c;并且能夠做到自動發送測試報告到相關人員的電子郵箱中。Jenkins 正好可以很好的完成以上訴求…

sql數據類型詳解

BCD碼1字符1/2字節 ASC碼1字符1字節 GB2312碼1字符2字節 BIG5碼1字符5字節 (1)二進制數據類型 二進制數據包括 Binary、Varbinary 和 Image  Binary 數據類型既可以是固定長度的(Binary),也可以是變長度的。  Binary[(n)] 是 n 位固定的二進制數據。其中&#xff0c;n 的取…

論公眾號內卷

關注若川視野, 回復"pdf" 領取資料&#xff0c;回復"加群"&#xff0c;可加群長期交流學習曾幾何時公眾號文章的標題單純且沒有套路七年前的我就是這樣僅僅把公眾號當做一個寫文章的博客平臺甚至是像有道云一樣的在線筆記平臺當時的標題是這樣子滴《hashma…

PHP 利用Mail_MimeDecode類提取郵件信息

轉載鏈接:http://blog.csdn.net/laijingyao881201/article/details/5512693 重點為one_mail函數。利用Mail_mimeDecode類從郵件中提取郵件頭和郵件正文。 <?php header("content-type:text/html; charsetUTF-8"); /** record kid words and insert into databa…

【轉】概要設計說明書

概要設計說明書 一&#xff0e; 引言 1&#xff0e; 編寫目的 從該階段開發正式進入軟件的實際開發階段&#xff0c;本階段完成系統的大致設計并明確系統的數據結構與軟件結構。在軟件設計階段主要是把一個軟件需求轉化為軟件表示的過程&#xff0c;這種表示只是描繪出軟件的…

程序異常異常代碼: 0xc0000005_Java基礎:看完這篇你還怕碰到異常嗎?

前言在日常的開發以及平時的學習練習中&#xff0c;異常相信對于大家來講并不陌生&#xff0c;但是對于異常的具體使用、底層實現以及分類等等可能并不是很了解。今天我就抽出了一點時間系統的整理了異常的各個知識點&#xff0c;希望能夠幫助到大家對于Java 異常的理解與學習。…

寫給初中級前端工程師的進階指南

學習一門新技術的時候&#xff0c;最大的苦惱之一&#xff0c;大概就是不知道從何入手。典型的情況是&#xff0c;你大概知道學會以后&#xff0c;這門技術可以幫你解決什么問題。但是&#xff0c;怎么才能學會、循序漸進的學習路線是什么、學習范圍有多大的深度和廣度、涉及到…

同一頁面中引入多個JS庫產生的沖突解決方案(轉)

發生JS庫沖突的主要原因&#xff1a;與jQuery庫一樣&#xff0c;許多JS庫都使用‘$’符號作為其代號。因此在一個頁面中引入多個JS庫&#xff0c;并且使用‘$’作為代號時&#xff0c;程序不能識別其代表哪個庫&#xff08;這個是我自己的解釋&#xff0c;但更深的原因就必須深…

不用安裝Oracle Client如何使用PLSQL Developer

1. 下載oracle的客戶端程序包&#xff08;30M&#xff09;只需要在Oracle下載一個叫Instant Client Package的軟件就可以了&#xff0c;這個軟件不需要安裝&#xff0c;只要解壓就可以用了&#xff0c;很方便&#xff0c;就算重裝了系統還是可以用的。下載地址&#xff1a;http…

input file的默認value清空與賦值方法

轉載鏈接&#xff1a;http://www.jb51.net/article/24872.htm出于安全性考慮&#xff0c;JS是不能直接設置File的value值的&#xff0c;下面是我總結出來的方法第1個方法是大多人傳統做法&#xff0c;替換HTML代碼&#xff0c;樓上的已經用到了&#xff0c;我不過是用正則優化一…

python中o_Python I/O與進程的詳細講解

I/Owith語句with context_expression [as target(s)]:with-bodycontext_expression返回值遵從上下文管理協議&#xff0c;包含__enter__()與__exit__()方法&#xff0c;as語句的target(s)得到的是__enter__()返回值&#xff0c;執行with-body后會調用上下文管理器的__exit__()方…