NewMoring

          與Java同路,贏在未來。

          統計

          積分與排名

          http://bbs.javawind.net/index.jspx

          http://www.chubeibao.com/bbs/index.php

          http://www.java2000.net/

          http://www.javaeye.com/

          http://www.javathinker.org/index.jsp

          http://www.programbbs.com/bbs/index.asp

          最新評論

          初探SchemaExport工具使用(轉帖)

          本節內容

          • 引入
          • SchemaExport工具
          • SchemaUpdate工具
          • 實例分析
          • 結語

          引入

          我其實都是一直先編寫持久化類和映射文件,然后使用SchemaExport工具生成數據庫架構。這樣的方式就是領域驅動設計/開發(DDD,Domain Driven Design/Development)。我的理解是系統的設計應該基于對象模型,主要考慮對象的設計和邏輯上,然后按照對象模型建立數據庫關系模型,這才是現在面向對象開發的步驟,并不是上一篇先設計數據庫然后再設計對象。用一幅圖可以形象的說明領域驅動設計:

          領域驅動設計模型

          當在設計時,我們的領域模型需要改變,只需修改NHibernate結構和應用程序,不需要修改數據庫架構,只要利用SchemaExport工具重新生成數據庫架構就可以了。但是使用數據庫只是其中一種方式,我們也可以使用XML文件來存儲數據。

          SchemaExport工具

          NHibernate的hbm2dll提供SchemaExport工具:給定一個連接字符串和映射文件,不需輸入其他東西就可以按照持久化類和映射文件自動生成數據庫架構,現在SchemaExport工具還不是很強大,但是一般應用足夠了,它還是一個相當原始的API還在不斷改進。

          SchemaExport工具就是把DDL腳本輸出到標準輸出,同時/或者執行DDL語句。SchemaExport工具提供了三個方法,分別是Drop()、Create()、Execute(),前兩個方法實質是調用Execute()方法。通常使用Execute()方法來生成數據庫架構的。

          SchemaUpdate工具

          在NHibernate2.0中新添加SchemaUpdate工具,可以用來更新數據庫架構。但是我覺得沒有什么作用,因為它不能Drop現有的表或列,也不能更新現有的列,只能添加新的表和列。如果我需要刪除表或者列或者修改其中列,SchemaUpdate工具就顯得無能為力了。

          實例分析

          知道了上面的知識就好好實戰一下:看看具體怎么使用呢?

          1.SchemaExport工具實戰

          通常我們使用生成數據庫架構代碼實例像這樣:

          Configuration cfg=new Configuration();
          cfg.Configure();
          SchemaExport export =new SchemaExport(cfg);
          export.Execute(....);

          1.準備工作

          現在數據訪問測試層新建一SchemaExportFixture.cs文件用于測試生成實戰。聲明一個全局變量_cfg,編寫 [SetUp]方法在每個測試方法執行之前調用:

          TestFixture]
          public class SchemaExportFixture
          {
          private Configuration _cfg;
          [SetUp]
          public void SetupContext()
          {
          _cfg = new Configuration();
          _cfg.Configure();
          }
          //測試......
          }

          2.測試Drop(script, export)方法

          Test]
          public void DropTest()
          {
          var export = new SchemaExport(_cfg);
          export.Drop(true, true);
          }

          Drop(script, export)方法根據持久類和映射文件執行刪除數據庫架構。有兩個參數,第一個為True就是把DDL語句輸出到控制臺,第二個為True就是根據持久類和映射文件執行刪除數據庫架構操作,經過調試可以發現Drop(script, export)方法其實質是執行了Execute(script, export, true, true)方法。

          3.測試Create(script, export)方法

          Test]
          public void CreateTest()
          {
          var export = new SchemaExport(_cfg);
          export.Create(true, true);
          }

          Create(script,export)方法根據持久類和映射文件先刪除架構后創建刪除數據庫架構。有兩個參數,第一個為True就是把DDL語句輸出到控制臺,第二個為True就是根據持久類和映射文件先執行刪除再執行創建操作,經過調試可以發現這個方法其實質是執行Execute(script,export, false, true)方法。

          4.測試Execute(script, export, justDrop, format)方法

          Test]
          public void ExecuteTest()
          {
          var export = new SchemaExport(_cfg);
          export.Execute(true, true, false, false);
          }

          Execute(script, export, justDrop, format)方法根據持久類和映射文件先刪除架構后創建刪除數據庫架構。有四個參數,第一個為True就是把DDL語句輸出到控制臺;第二個為True就是根據持久類和映射文件在數據庫中先執行刪除再執行創建操作;第三個為false表示不是僅僅執行Drop語句還執行創建操作,這個參數的不同就擴展了上面兩個方法;第四個參數為false表示不是格式化輸出DDL語句到控制臺,是在一行輸出的。

          所謂格式化輸出就像這樣:

          格式化輸出

          一行輸出就像這樣:

          一行輸出

          5.測試Execute(script, export, justDrop, format, connection, exportOutput)方法

          Test]
          public void ExecuteOutTest()
          {
          var export = new SchemaExport(_cfg);
          var sb = new StringBuilder();
          TextWriter output = new StringWriter(sb);
          export.Execute(true, false, false, false, null, output);
          }

          Execute(script, export, justDrop, format, connection, exportOutput)方法根據持久類和映射文件先刪除架構后創建刪除數據庫架構。有六個參數,第一個為True就是把DDL語句輸出到控制臺;第二個為false就是不執行DDL語句;第五個為自定義連接。當export為true執行語句時必須打開連接。該方法不關閉連接,null就是使用默認連接,最后一個參數自定義輸出,這里我輸出到TextWriter中。

          2.SchemaUpdate工具實戰

          現在數據訪問測試層新建一SchemaUpdateFixture.cs文件用于測試生成實戰。先聲明一個全局變量_cfg:

          private Configuration _cfg;

          這里我用另外一種方式配置映射文件,先定義兩個映射XML分別代表舊的和新的這樣才能體現測試更新數據庫架構的意義。

          舊映射XML:這里我使用Product持久化類,由于在之前我們定義了Product持久化類,這里直接模擬定義映射XML:擁有主鍵ProductId和Name字段。

          public const string product_xml =
          "<?xml version='1.0' encoding='utf-8' ?>" +
          "<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'" +
          "                 assembly='DomainModel'" +
          "                 namespace='DomainModel'>" +
          "  <class name='DomainModel.Entities.Product,DomainModel'>" +
          "    <id name='ProductId'>" +
          "      <generator class='native'/>" +
          "    </id>" +
          "    <property name='Name'/>" +
          "  </class>" +
          "</hibernate-mapping>";

          新映射XML:更新上面映射XML:主鍵ProductId(沒有改變);Name字段:添加不可為空和長度為50;另外增加了Cost字段,類型為float不可為空。

          public const string newproduct_xml =
          "<?xml version='1.0' encoding='utf-8' ?>" +
          "<hibernate-mapping xmlns='urn:nhibernate-mapping-2.2'" +
          "                 assembly='DomainModel'" +
          "                 namespace='DomainModel'>" +
          "  <class name='DomainModel.Entities.Product,DomainModel'>" +
          "    <id name='ProductId'>" +
          "      <generator class='native'/>" +
          "    </id>" +
          "    <property name='Name' not-null='true' length='50' />" +
          "    <property name='Cost' type='float' not-null='true'/>" +
          "  </class>" +
          "</hibernate-mapping>";

          測試前利用舊映射XML創建數據庫架構:使用[SetUp]在測試前執行,按照舊映射XML創建數據庫架構并格式化輸出DDL語句:

          SetUp]
          public void SetupContext()
          {
          //模擬舊系統
          _cfg = new Configuration();
          _cfg.Configure();
          _cfg.AddXml(product_xml);
          var export = new SchemaExport(_cfg);
          export.Execute(true, true, false, true);
          }

          測試更新數據庫架構:使用SchemaUpdate類提供的唯一的Execute(script, doUpdate)方法按照新映射XML更新數據庫架構:

          Test]
          public void UpdateExistingDatabaseSchemaTest()
          {
          _cfg = new Configuration();
          _cfg.Configure().AddXml(newproduct_xml);
          var update = new SchemaUpdate(_cfg);
          update.Execute(true, true);
          }

          測試輸出結果如圖所示,如果你覺得不放心再看看數據庫Product表。

          輸出結果

          看到了嗎?這顯然不是我要求的,首先按照舊映射XML創建了數據庫架構,但是更新數據庫架構顯得無能為力,僅僅增加了Cost字段,我想更新Name字段屬性為不可為空和長度為50,但是SchemaUpdate工具不能做到!我覺得這個類目前還沒有什么作用,期待下一個版本來完善。

          結語

          這篇文章通過實例介紹NHibernate中提供兩個實用工具SchemaExport工具利用持久化類和映射文件生成數據庫架構。SchemaUpdate工具通過持久化類和映射文件更新數據庫架構。

          posted on 2009-05-04 17:11 清晨 閱讀(524) 評論(0)  編輯  收藏 所屬分類: hibernate 的相關知識


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 遵化市| 社旗县| 蒙阴县| 贵定县| 伊通| 永善县| 腾冲县| 永丰县| 卓尼县| 扬中市| 措美县| 刚察县| 扶沟县| 海原县| 额济纳旗| 丹江口市| 新巴尔虎右旗| 元氏县| 固安县| 灵宝市| 荔浦县| 新宁县| 永修县| 天津市| 六安市| 婺源县| 涿州市| 正定县| 宜宾市| 南陵县| 临夏县| 汨罗市| 灵寿县| 莱西市| 连山| 九龙县| 班戈县| 密山市| 鹿邑县| 华阴市| 青海省|