第二章:NHibernate配置的总体流程

  上一章节,我们了解了NHibernate的介绍和用途,那NHibernate如何引入到项目中,并且被运用呢,这一章我们开始操作吧!

  注:本材料开始本人研究3天研究出来的,绝对最新,请仔细阅读!!!

  首先要有准备工作:

  1、下载NHibernate:当前版本2.0.1(较新版本)下载地址:http://sourceforge.net/projects/nhibernate/

  2、下载CodeSmith:http://www.codesmithtools.com/
  3、下载NHibernate模板:http://files.cnblogs.com/abluedog/nhibernate_template.rar

  

  关于NHibernate2.1版本的一些说明:

NHibernate2.1版本改变了ByteCode延迟加载机制,有三种3种IoC框架动态代理方式,分别为:Castle框架、LinFu框架、Spring.Net框架。我们只要选择一种,在配置文件中配置proxyfactory.factory_class节点。

如果使用Castle.DynamicProxy2动态代理,引用NHibernate.ByteCode.Castle.dll程序集并配置proxyfactory.factory_class节点为<property name="proxyfactory.factory_class"> NHibernate.ByteCode.Castle.ProxyFactoryFactory,NHibernate.ByteCode.Castle</property>

如果使用LinFu.DynamicProxy动态代理,引用NHibernate.ByteCode.LinFu.dll程序集并配置proxyfactory.factory_class节点为<property name="proxyfactory.factory_class"> NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu</property>

如果使用Spring.Aop动态代理,引用NHibernate.ByteCode.Spring.dll程序集并配置proxyfactory.factory_class节点为<property name="proxyfactory.factory_class"> NHibernate.ByteCode.Spring.ProxyFactoryFactory,NHibernate.ByteCode.Spring</property>

另外NHibernate2.1要求.NET2.0 SP1以上版本 (System.DateTimeOffset),请使用VS2005的,务必打上Sp1补丁。推荐使用VS2008以上版本。

  OK,准备工作结束,开始讲解如何运用这3个工具:

  首先打开CodeSmith(注意CodeSmith一定要注册),导入NHibernate模板:如图

  第二章:NHibernate配置的总体流程_第1张图片

  注意:我在网上搜索很多关于NHibernate模板,始终没有找到,这个模板算是比较好的,但是要修改一下类生成文件和映射生成文件的内容:

  1、打开NHibernate.class.cst,找到如下代码:把所有生成 get、set 的 public 修饰符改为 public virtual ,注绿色virtual为添加部分

  

代码
   
   
#region Public Properties

<% if (SourceTable.PrimaryKey.MemberColumns.Count == 1 ) { %>
public virtual <%= IdMemberType(SourceTable) %> <%= IdName(SourceTable) %>
{
get { return <%= IdMemberName(SourceTable) %> ;}
<% if (IdMemberType(SourceTable) == " string " ) { %>
set
{
if ( value != null && value.Length > <%= ColumnLength(SourceTable.PrimaryKey.MemberColumns[ 0 ]) %> )
throw new ArgumentOutOfRangeException( " Invalid value for <%= IdName(SourceTable) %> " , value, value.ToString());
<%= IdMemberName(SourceTable) %> = value;
}
<% } else { %>
set { <%= IdMemberName(SourceTable) %> = value;}
<% } %>
}
<% } %>

<% foreach (ColumnSchema column in SourceTable.NonKeyColumns) { %>
public virtual <%= MemberType(column) %> <%= PropertyName(column) %>
{
get { return <%= MemberName(column) %> ; }
<% if (MemberType(column) == " string " ) { %>
set
{
if ( value != null && value.Length > <%= ColumnLength(column) %> )
throw new ArgumentOutOfRangeException( " Invalid value for <%= PropertyName(column) %> " , value, value.ToString());
<%= MemberName(column) %> = value;
}
<% } else { %>
set { <%= MemberName(column) %> = value; }
<% } %>
}

<% } %>
<% foreach (TableKeySchema foreignKey in SourceTable.ForeignKeys) { %>
public <%= ManyToOneClass(foreignKey) %> <%= ManyToOneName(foreignKey) %>
{
get { return <%= ManyToOneMemberName(foreignKey) %> ; }
set { <%= ManyToOneMemberName(foreignKey) %> = value; }
}

<% if ((foreignKey.ForeignKeyTable == SourceTable) && (foreignKey.PrimaryKeyTable == SourceTable)) { %>
public virtual <%= CollectionType(foreignKey) %> <%= CollectionName(foreignKey) %>
{
get { return <%= CollectionMemberName(foreignKey) %> ; }
set { <%= CollectionMemberName(foreignKey) %> = value; }
}

<% } %>
<% } %>
<% foreach (TableKeySchema primaryKey in SourceTable.PrimaryKeys) { %>
<% if (IsManyToManyTable(primaryKey.ForeignKeyTable)) { %>
public virtual <%= CollectionType(primaryKey) %> <%= CollectionManyToManyName(primaryKey) %>
{
get
{
if ( <%= CollectionManyToManyMemberName(primaryKey) %>== null )
{
<%= CollectionManyToManyMemberName(primaryKey) %> = <%= NewCollectionType(primaryKey) %> ;
}
return <%= CollectionManyToManyMemberName(primaryKey) %> ;
}
set { <%= CollectionManyToManyMemberName(primaryKey) %> = value; }
}

<% } else if (IsOneToOneTable(primaryKey)) { %>
public virtual <%= OneToOneClass(primaryKey) %> <%= OneToOneName(primaryKey) %>
{
get { return <%= OneToOneMemberName(primaryKey) %> ; }
set { <%= OneToOneMemberName(primaryKey) %> = value; }
}

<% } else if (IsSubClassTable(primaryKey)) { %>
<% } else { %>
public virtual <%= CollectionType(primaryKey) %> <%= CollectionName(primaryKey) %>
{
get
{
if ( <%= CollectionMemberName(primaryKey) %>== null )
{
<%= CollectionMemberName(primaryKey) %> = <%= NewCollectionType(primaryKey) %> ;
}
return <%= CollectionMemberName(primaryKey) %> ;
}
set { <%= CollectionMemberName(primaryKey) %> = value; }
}

<% } %>
<% } %>


#endregion

  

  2、打开NHibernate.hbm.cst,映射由2.0改为2.2 

  
  
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< hibernate - mapping xmlns = " urn:nhibernate-mapping-2.2 " >
< class <%= ClassNameAtt(SourceTable) %><%= ClassTableAtt(SourceTable) %>>

  OK,NHibernate模板修改成功,开始生成实体与映射文件

  最近在做一个进销存联系,数据表多了点,不利于学习,但是你看明白了,可以做一个数据表的小例子,下面是数据表的截图:

  第二章:NHibernate配置的总体流程_第2张图片

  生成持久化类 与 映射文件

  右键NHibernate.cst点击Execute,出现下面界面

  第二章:NHibernate配置的总体流程_第3张图片

  OutputDirectory:你的实体与映射文件保存的文件夹,建议先保存到一个单独的文件夹;

  SourceDatabase:是你第一次选择时需要配置一个连接字符串,配置好后Code Smith将记录下来;

  Assembly:写上你的项目的实体类库名,比如我做的进销存,实体类库叫GoodsMnanage.Model,在以后的Configuration创建时需要加载这个名字;

  Namespace:写上你的实体文件产生的路径。

   如果不明白可以对比一下我的项目截图:

  第二章:NHibernate配置的总体流程_第4张图片

  开始配置项目

  开发工具:vs2005/vs2008,SQL2005

  首先建一个小的web项目,以往的材料全是简单的实体和一个控制台文件,今天我们运用到3层的web项目中:

  根据截图,我们可以在Model层中建2个文件夹,所有***.cs类全部放在Entities文件夹中

注意:NHibernate默认使用代理功能,要求持久化类不是sealed的,而且其公共方法、属性和事件声明为virtual。

也就是说所有生成属性的set、get方法必须写成下面这种类型:检查一下你的实体类是这样写的吗,这就是为什么我们要修改NHibernate模板成为Public Virture了

public virtual string Name
  {
    get { return name; }
    set{ name = value;}
  }

在这里,类中的字段要设置为virtual,否则出现“failed: NHibernate.InvalidProxyTypeException : The following types may not be used as proxies: NHibernateSample.Domain.Entities.Customer: method get_Id should be virtual,method set_Id should be virtual”异常。

  所有***.hbm.xml映射文件全部放在Mappings文件夹中;

注意:所有Mapping下的***.hbm.xml的属性中生成的操作默认生成操作为“内容”,这里需要修改为“嵌入的资源”生成,因为NHibernate是通过查找程序集中的资源文件               映射实体;否则出现“ failed: NHibernate.MappingException : No persister for: NHibernateSample.Domain.Entities.Customer”异常

  然后在DAO层中首先添加版本为2.0.1中的NHibernate.dll,然后建一个NHibernateHelper.cs类

  

代码
   
   
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Cfg;

namespace GoodsManage.DAO
{
public static class NHibernateHelper
{
private static ISession session = null ;
private static ITransaction trans = null ;

/// <summary>
/// 获取打开的session
/// </summary>
/// <returns></returns>

public static ISession getSession()
{
      //这里的GoodsManage.Model就是我们在CodeSmith中配置生成文件时的Assembly中的内容
Configuration conf
= new Configuration().AddAssembly( " GoodsManage.Model " );
//建立工厂
      ISessionFactory factory = conf.BuildSessionFactory();
      //打开工厂
session
= factory.OpenSession();

return session;
}

/// <summary>
/// 获取事务
/// </summary>
/// <returns></returns>
public static ITransaction getTrans()
{
      //创建事务
trans
= session.BeginTransaction();
return trans;
}
}
}

  之后新建类写增删改查的方法,写个简单的Get方法:

  
  
public static TbUser getUserById( int userId)
{
TbUser user
= session.Get < TbUser > (userId);
return user;
}

  之后建DAL层,添加DAO的应用

  
  
public static TbUser getUserById( int userId)
{
TbUser user
= tb_UserServer.getUserById(userId);
return user;
}

  最后开始最后一层,表示层,最重要的就是web.config的配置:

  首先要在表示层添加DAO、DAL的应用,最重要的是添加NHibernate.ByteCode.Castle.dll的引用

   web.config的配置

代码
   
   
< configuration >
< configSections >
< section name = " hibernate-configuration " type = " NHibernate.Cfg.ConfigurationSectionHandler, NHibernate " />
</ configSections >
< hibernate - configuration xmlns = " urn:nhibernate-configuration-2.2 " >
< session - factory >
< property name = " dialect " > NHibernate.Dialect.MsSql2005Dialect </ property >
< property name = " connection.provider " > NHibernate.Connection.DriverConnectionProvider </ property >
< property name = " connection.connection_string " > Server = .;DataBase = db_GoodsManage;user id = sa;password = 123456 </ property >
< property name = " proxyfactory.factory_class " > NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle </ property >
</ session - factory >
</ hibernate - configuration >
< appSettings />
< connectionStrings />

  dialect:数据库版本,我用的Sql2005,如果是2000,可以写MsSql2000Dialect

  connection.provider:连接数据库的提供者Nhibernate

  connection.connection_string:连接数据库字符串

  proxyfactory.factory_class:(关于NHibernate2.1.0的说明)

注意:如果没有配置proxyfactory.factory_class,会出现:

The ProxyFactoryFactory was not configured.
Initialize 'proxyfactory.factory_class' property of the session-factory configuration section with one of the available NHibernate.ByteCode providers.
Example:
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
Example:
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>

  最后在新建一个页面:添加一个按钮,双击按钮

  
  
protected void Button1_Click( object sender, EventArgs e)
{
TbUser user
= tb_UserManage.getUserById( 1 );
Response.Write(
" <script>alert(' " + user .Name + " ')</script> " );
}

 运行,点击按钮时

第二章:NHibernate配置的总体流程_第5张图片

  好了,结束了,我们的总体配置NHibernate流程也告一段落了,希望大家能够看懂,我开始学习HQL了,希望早点学会,总结大家看,如果本节存在什么问题,请大家指出,感谢大家的支持!

你可能感兴趣的:(Hibernate)