這次主要用的數據庫是sql server 2005,而裏面還有圖片要存放,所以這裏寫個例子對圖片等二進制數據的存放進行操作。
代碼還是上傳到csdn,地址上傳後再定。
開發環境:vs2008sp1, nunit, nhibernate1.21
先新建一個空項目或一個控制檯程序,名字爲HiberDemo2。
加入必要的dll文件,並設置爲複製到項目中。
還是老規矩,建Domain和Mappings目錄分別放pojo類和hbm.xml文件。
這次先寫pojo吧,Domain目錄下面新建一個Friends.cs
- public class Friends
- {
- virtual public int id { get; set; }
- virtual public string name { get; set; }
- virtual public byte[] pic { get; set; }
- }
再是Mapping中建立對應的Friends.hbm.xml
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="HiberDemo2" namespace="HiberDemo2.Domain">
- <class name="Friends">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="name"/>
- <property name="pic" type="BinaryBlob" length="9000"/>
- </class>
- </hibernate-mapping>
然後在根目錄中建立hibernate.cfg.xml配置文件
- <?xml version="1.0" ?>
- <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
- <session-factory>
- <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
- <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
- <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
- <property name="connection.connection_string">Server=USER;Initial Catalog=MyTest;User Id=sa;Password=sa</property>
- <property name="show_sql">true</property>
- <mapping file="Mappings/Friends.hbm.xml"/>
- </session-factory>
- </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,並把圖片寫到文件中。代碼如下:
- namespace HiberDemo2.test
- {
- [TestFixture]
- public class testFriends
- {
- private static Configuration cfg;
- private static ISession session;
- [TestFixtureSetUp]
- public void Initall()
- {
- cfg = new Configuration();
- cfg.Configure();
- session = cfg.BuildSessionFactory().OpenSession();
- }
- [Ignore]
- public void testCreate()
- {
- new SchemaExport(cfg).Create(true, true);
- }
- [Test]
- public void testSave()
- {
- var fs = new FileStream("c:/temp/001.jpg", FileMode.Open);
- var reader = new BinaryReader(fs);
- var f = new Friends();
- f.name = "f1";
- f.pic = reader.ReadBytes((int) fs.Length);
- reader.Close();
- fs.Close();
- session.BeginTransaction();
- session.Save(f);
- session.Transaction.Commit();
- }
- [Test]
- public void testRetreive()
- {
- var l = session.CreateCriteria(typeof(Friends)).List();
- Assert.Greater(l.Count, 0);
- var f = (Friends) l[0];
- var fs = new FileStream("c:/temp/mypic.jpg", FileMode.Create);
- var writer = new BinaryWriter(fs);
- writer.Write(f.pic);
- writer.Close();
- fs.Close();
- }
- }
- }
其中testCreate只是在第一次測試中單獨運行,後面不用再測試了,所以後面改成了Ignore標籤。它輸出下面的建表sql語句
- if exists (select * from dbo.sysobjects where id = object_id(N'Friends') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Friends
- create table Friends (
- id INT IDENTITY NOT NULL,
- name NVARCHAR(255) null,
- pic VARBINARY(MAX) null,
- primary key (id)
- )
寫入數據的時候,在上面代碼的28行處,請你自己改圖片的路徑。
testRetrieve運行完後,在c:/temp/目錄下應該有一張mypic.jpg圖片。