这次主要用的数据库是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图片。