首页logo
  •  

jonllen

金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。

个人档案

jonllen
心情闪存 | 给他留言
妮称:jonllen
来自:中国. 湖南. 湘潭
简述:金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。
博客日历

我的第一个NHibernate2.1.2.GA程序事例

分类:Asp.Net

对ORM(Object/Relation Mapping)技术了解的都知道,NHibernate是基于.Net的一种数据持久化的框架。之前在Java里了解过Hibernate框架,但平时开发还是.Net用得比较多,而且目前面向对象和关系型数据库的开发应用仍然是主流,所以觉得有必要去了解学习NHibernate这个优秀的ORM框架。

一、类库

在我的这个NHibernate2.1.2.GA版的程序事例中,是使用VS2005工具开发的,引用NHibernate的相关类库文件如下:

名称功能
NHibernate.dll NHibernate核心类库
Iesi.Collections.dll 提供集合运算功能
NHibernate.ByteCode.Castle.dll 使用Castle动态代理
Castle.Core.dll Castle代理核心类库
Castle.DynamicProxy2.dll Castle动态代理
Antlr3.Runtime.dll 语法分析和词法分析(未使用)

二、配置

NHibernate可以有几种加载配置的方式:Web.Config/App.Config、hibernate.cfg.xml、编码指定配置文件。因为在我的这个事例是Asp.Net的NHibernate网站程序,所以在Web.Config的configSections下增加section节点来配置NHibernate。也可以独立出hibernate.cfg.xml配置文件,放在网站Bin目录下,使用如下方式实例化:

Configuration config = new Configuration().Configure();

NHibernate默认会在目录下自动查找hibernate.cfg.xml配置文件。

如下为我的Web.Config配置文件内容:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
	<appSettings/>
	<connectionStrings/>
  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory name="NHibernateDemo">
      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
      <property name="connection.connection_string">
        Data Source=.\SQL2005;Initial Catalog=Jonllen;
        Integrated Security=True;Pooling=False
      </property>
      <property name="adonet.batch_size">10</property>
      <property name="show_sql">true</property>
      <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
      <property name="use_outer_join">true</property>
      <property name="command_timeout">10</property>
      <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
      <property name="proxyfactory.factory_class">
        NHibernate.ByteCode.Castle.ProxyFactoryFactory,
        NHibernate.ByteCode.Castle
      </property>
      <mapping assembly="NHibernateDemo.Domain"/>
    </session-factory>
  </hibernate-configuration>
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender, log4net">
      <layout type="log4net.Layout.PatternLayout, log4net">
        <param name="ConversionPattern" value="%d %p %m%n" />
      </layout>
    </appender>
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender,log4net" >
      <param name="File" value="log.txt" />
      <param name="AppendToFile" value="true" />
      <param name="DatePattern" value="yyyy.MM.dd" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <conversionPattern value="%d %p %m%n" />
      </layout>
    </appender>
    <root>
      <priority value="DEBUG" />
      <appender-ref ref="ConsoleAppender" />
    </root>
    <logger name="NHibernate" additivity="false">
      <level value="WARN"/>
      <appender-ref ref="RollingFile" />
      <appender-ref ref="ConsoleAppender" />
    </logger>
    <logger name="NHibernate.SQL" additivity="false">
      <level value="ALL"/>
      <appender-ref ref="RollingFile" />
      <appender-ref ref="ConsoleAppender" />
    </logger>
  </log4net>
  <system.web>
		<compilation debug="true">
			<assemblies>
      </assemblies>
    </compilation>
		<authentication mode="Forms"/>
	</system.web>
</configuration>

三、映射

NHibernate提供了几种方式的实体关系映射,比较灵活的是使用xml文件进行映射,将实体类与数据表的关系描述配置。使用这种方式要指定NHibernate配置session-factory中mapping的assembly实体程序集,*.hbm.xml实体映射文件属性的生成操作都要设置为嵌入的资源,因为NHibernate是通过查找程序集中的资源文件映射实体的。

如下为我的User.hbm.xml映射文件内容:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateDemo.Domain"
   namespace="NHibernateDemo.Domain.Entities">

  <class name ="User" table="bl_user" >
    <id name="UserId" column ="userId">
      <generator class ="native"/>
    </id>
    <property name ="Username"/>
    <property name ="Password"/>
    <property name ="LoginTimes"/>
    <property name ="RegisterDate"/>
    <property name ="UserStatus"/>
    <property name ="TemplateDisplay"/>
  </class>
  
</hibernate-mapping>

NHibernate也提供在编码时自定义映射方式,如使用Fluent在创建ISessionFactory时动态添加要映射的程序集。另外,我曾经在Hibernate中可以使用注解方式,即直接在实体类上添加注释来映射,我想在.Net中NHibernate应该也可以使用元数据进行实体映射。

四、延迟加载

NHibernate2.1版本提供三种3种框架动态代理,分别为Castle框架、LinFu框架、Spring.Net框架,以实现延迟加载功能。在我的这个NHibernate事例中是使用的Castle框架,它要求持久化类不是sealed密封类,且其公共方法、属性和事件声明必须为virtual,否则将出现如下错误:

The following types may not be used as proxies:NHibernateDemo.Domain.Entities.User: method get_UserId should be 'public/protected virtual' or 'protected internal virtual'

如果非得每个实体属性都要为virtual好象有点强人所难,于是我把User.hbm.xml中class的lazy="false",改为默认不使用延迟加载就没问题了。如果能正常使用延迟加载功能固然是好,但一般取数据实体里的属性一般都会是确定的,实在不行也可以在业务逻辑层里再手动填充实体属性,所以也不一定就要使用延迟加载。

目前.Net实现动态代理功能似乎都对现有的有侵入性,不是要求继承类就是有其它的实现条件。而之所以要有virtual这个条件是因为创建代理对象需要override实体类型的方法属性,以实现对方法属性的拦截处理,植入执行前和执行后的逻辑,以实现延迟加载的功能。而在Java中则专门提供了InvocationHandler代理接口,并且所有方法默认都可以Override,因此实现Aop动态代理就很简单。

本事例VS2005工程源代码下载:NHibernateDemo

标签:Asp.Net ORM框架
  • posted@ 2011-03-26 23:19
  • update@
  • 阅读(9402)
  • 评论(2)
评论
1楼 青岛红酒 2011-06-01 10:18:00
来转转啦~~~
2楼 金顺道物流 2011-06-01 10:18:27
来看看滴
发表评论
*必填
回复通知我
*必填

博文推荐