[转]NHibernate第一个实例(基于NHibernate-3.3.2)
最近因为项目的需要,数据层想换成NHibernate,我以前在做JAVA时虽曾接触过Hibernate,但好些年过去了,做第一个实例居然费了我好些精力,现把成功的例子贴出来。
1、建立数据表和实体对象
数据库是用的MSSQL2008,建表语句就不贴了,总共就3个字段。下面是实体对象代码
using System; namespace Example.Domain { public class Item { private int id; private decimal price; private string description; public virtual int Id { get { return id; } set { id = value; } } public virtual decimal Price { get { return price; } set { price = value; } } public virtual string Description { get { return description; } set { description = value; } } } }
2、在Item对象的同一项目(同一目录)下新建一个与实体对象同名的XML文件,以“hbm.xml”为扩展名。如:Item.hbm.xml
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Example.Domain" namespace="Example.Domain"> <!-- Class has to be non-lazy because Medium Trust Level restrictions prevent proxy generation from working. --> <class name="Item" table="Item" lazy="false"> <id name="Id"> <generator class="native" /> </id> <property name="Price" /> <property name="Description" /> </class> </hibernate-mapping>
这里重点说一下 assembly 和 namespace属性。
assembly:集合的名称,如果在一个项目下有许多个实体对象,我们只需要指定这个属性,并在web.config中加入 如: “<mapping assembly="Example.Domain"/>”就行了。
namespace:命名空间,如果设定了这个属性,class的 name只要指定与实体对象同名就行了。
还有要特别注意的是:XML文件的默认生成操作为“内容”,这里 需要修改为“嵌入的资源”生成,因为NHibernate是通过查找程序集中的资源文件映射实体。这样在生成类库DLL文件时,这个XML文件才会打包进 去,同时名称要自动修改为“Example.Domain.Item.hbm.xml”。
3、web.config中进行配置
<?xml version="1.0"?> <configuration> <configSections> <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false"/> <!-- Important under Medium Trust --> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/> <!-- Important under Medium Trust --> </configSections> <appSettings/> <connectionStrings/> <system.web> <compilation debug="true"> </compilation> <authentication mode="Windows"/> <pages enableViewState="false" enableViewStateMac="false"> </pages> <httpModules> <add name="CurrentSessionModule" type="NHibernate.Example.Web.CurrentSessionModule"/> </httpModules> </system.web> <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <bytecode-provider type="null"/> <session-factory> <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property> <property name="connection.connection_string"> Data Source=PC-20110811NRNE\SQLEXPRESS;initial catalog=Northwind;Integrated Security=true;User ID=user1;Password=pwd1 </property> <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property> <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property> <property name="current_session_context_class">managed_web</property> <span style="BACKGROUND-COLOR: #ff6666"><span style="BACKGROUND-COLOR: #ffffff"> <property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory,NHibernate</property> <mapping assembly="Example.Domain"/> </span></span> </session-factory> </hibernate-configuration> <log4net> <!-- Define some output appenders --> <appender name="trace" type="log4net.Appender.TraceAppender, log4net"> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n"/> </layout> </appender> <appender name="console" type="log4net.Appender.ConsoleAppender, log4net"> <layout type="log4net.Layout.PatternLayout,log4net"> <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n"/> </layout> </appender> <root> <priority value="WARN"/> <appender-ref ref="trace"/> </root> </log4net> </configuration>
标红色背景的是要特别注意的地方。3.3.2版本的测试通过,从网上搜集的先前版本的例子都不正常了。
4、ISeesion调用代码
using System.Web; using System.Web.Hosting; using NHibernate.Cfg; using Example.Domain; namespace NHibernate.Example.Web { public class ExampleApplication : HttpApplication { public static readonly Configuration Configuration; public static readonly ISessionFactory SessionFactory; static ExampleApplication() { log4net.Config.XmlConfigurator.Configure(); Configuration = new Configuration(); string nhConfigPath = HostingEnvironment.MapPath("~/App_Data/hibernate.cfg.xml"); if (File.Exists(nhConfigPath)) { Configuration.Configure(nhConfigPath); } SessionFactory = Configuration.Configure().BuildSessionFactory(); } public static ISession GetCurrentSession() { return SessionFactory.GetCurrentSession(); } } }
还有个类:
using System; using System.Web; using NHibernate.Context; namespace NHibernate.Example.Web { public class CurrentSessionModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(Application_BeginRequest); context.EndRequest += new EventHandler(Application_EndRequest); } public void Dispose() { } private void Application_BeginRequest(object sender, EventArgs e) { ManagedWebSessionContext.Bind(HttpContext.Current, ExampleApplication.SessionFactory.OpenSession()); } private void Application_EndRequest(object sender, EventArgs e) { ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, ExampleApplication.SessionFactory); if (session.Transaction.IsActive) { session.Transaction.Rollback(); } if (session != null) { session.Close(); } } } }
5、数据层封装类
using System; using System.Collections.Generic; using Example.Domain; namespace NHibernate.Example.Web.Persistence { public class ItemList { public IList<Item> GetAllItems() { return ExampleApplication.GetCurrentSession().CreateQuery("from Item").List<Item>(); } public void UpdateItem(Item item) { ExampleApplication.GetCurrentSession().SaveOrUpdateCopy(item); } public void DeleteItem(Item item) { ISession session = ExampleApplication.GetCurrentSession(); session.Delete(session.Load(typeof(Item), item.Id)); } public void InsertItem(Item item) { ExampleApplication.GetCurrentSession().Save(item); } } }
以上代码在我本机测试通过。

浙公网安备 33010602011771号