NHibernate小結之三

這次主要用的數據庫是sql server 2005,而裏面還有圖片要存放,所以這裏寫個例子對圖片等二進制數據的存放進行操作。

 

代碼還是上傳到csdn,地址上傳後再定。

 

開發環境:vs2008sp1, nunit, nhibernate1.21

 

先新建一個空項目或一個控制檯程序,名字爲HiberDemo2。

加入必要的dll文件,並設置爲複製到項目中。

 

還是老規矩,建Domain和Mappings目錄分別放pojo類和hbm.xml文件。

這次先寫pojo吧,Domain目錄下面新建一個Friends.cs

  1.     public class Friends
  2.     {
  3.         virtual public int id { getset; }
  4.         virtual public string name { getset; }
  5.         virtual public byte[] pic { getset; }
  6.     }

 

再是Mapping中建立對應的Friends.hbm.xml

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="HiberDemo2" namespace="HiberDemo2.Domain">
  3.     <class name="Friends">
  4.         <id name="id">
  5.             <generator class="native"></generator>
  6.         </id>
  7.         <property name="name"/>
  8.         <property name="pic" type="BinaryBlob" length="9000"/>
  9.     </class>
  10. </hibernate-mapping>

 

然後在根目錄中建立hibernate.cfg.xml配置文件

  1. <?xml version="1.0" ?>
  2. <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
  3.     <session-factory>
  4.         <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
  5.         <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
  6.         <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
  7.         <property name="connection.connection_string">Server=USER;Initial Catalog=MyTest;User Id=sa;Password=sa</property>
  8.         <property name="show_sql">true</property>
  9.         <mapping file="Mappings/Friends.hbm.xml"/>
  10.     </session-factory>
  11. </hibernate-configuration>

 

這裏說明一下,關鍵是hbm.xml文件中圖片字段用的是 type="BinaryBlob" length="9000", 對應於pojo中的byte[]類型。這個配置的來源是在NH的使用手冊的5.2小節NHibernate Types中有專門的講述,具體來說手冊中是以列表來說明NH中的類型與.net中類型的對應關係。那麼應用到我們的例子,NH中的BinaryBlob類型,對應於byte[],所以在hbm.xml中用NH的類型配,而POJO中直接寫.net中的對應類型即可!!

另外,在sql server2005中,varbinary是對應的類型。但如果你不給長度或者長度小於8000,它會將長度設爲8000或以下,這樣只能讀取很小的二進制文件,所以爲了將其設爲varbinary(max),可以讀取2G文件的,在hbm.xml中一定要設置長度大於8000,這樣創建表的sql語句纔會自動生成正確的語句,其sql語句見本文後面。

但長度只寫9000是不是會小呢,從我的例子來看,我的圖片字節大小有444k之大,讀取並寫入磁盤文件後沒有問題,所以這裏應該是可以的。

 

下面就是測試了。

新建一個test目錄,建一個testFriends類進行測試。

測試的內容有 1.創建對應的表 2.寫入一個POJO  3.讀出一個POJO,並把圖片寫到文件中。代碼如下:

  1. namespace HiberDemo2.test
  2. {
  3.     [TestFixture]
  4.     public class testFriends
  5.     {
  6.         private static Configuration cfg;
  7.         private static ISession session;
  8.         [TestFixtureSetUp]
  9.         public void Initall()
  10.         {
  11.             cfg = new Configuration();
  12.             cfg.Configure();
  13.             session = cfg.BuildSessionFactory().OpenSession();
  14.         }
  15.         [Ignore]
  16.         public void testCreate()
  17.         {
  18.             new SchemaExport(cfg).Create(truetrue);
  19.         }
  20.         [Test]
  21.         public void testSave()
  22.         {
  23.             var fs = new FileStream("c:/temp/001.jpg", FileMode.Open);
  24.             var reader = new BinaryReader(fs);
  25.             var f = new Friends();
  26.             f.name = "f1";
  27.             f.pic = reader.ReadBytes((int) fs.Length);
  28.             reader.Close();
  29.             fs.Close();
  30.             session.BeginTransaction();
  31.             session.Save(f);
  32.             session.Transaction.Commit();
  33.             
  34.         }
  35.         [Test]
  36.         public void testRetreive()
  37.         {
  38.             var l = session.CreateCriteria(typeof(Friends)).List();
  39.             Assert.Greater(l.Count, 0);
  40.             var f = (Friends) l[0];
  41.             var fs = new FileStream("c:/temp/mypic.jpg", FileMode.Create);
  42.             var writer = new BinaryWriter(fs);
  43.             writer.Write(f.pic);
  44.             writer.Close();
  45.             fs.Close();
  46.             
  47.         }
  48.     }
  49. }

 

 

其中testCreate只是在第一次測試中單獨運行,後面不用再測試了,所以後面改成了Ignore標籤。它輸出下面的建表sql語句

 

  1. if exists (select * from dbo.sysobjects where id = object_id(N'Friends') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Friends
  2. create table Friends (
  3.   id INT IDENTITY NOT NULL,
  4.    name NVARCHAR(255) null,
  5.    pic VARBINARY(MAX) null,
  6.    primary key (id)
  7. )

寫入數據的時候,在上面代碼的28行處,請你自己改圖片的路徑。

testRetrieve運行完後,在c:/temp/目錄下應該有一張mypic.jpg圖片。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章