NHibernate数据持久框架在多层项目开发中的应用(一)

作者:jargon

一、工程环境:

在Microsoft Visual.net新建一解决方案,新建三个工程:

1、数据层 Search.Data

2、业务逻辑层Search.Mid

3、表现层:Search.Web
项目结构如《使用Nhibernate框架,快速开发Dotnet应用》中的图所示。

二、编写数据层:

1、编写数据对象的XML描术文件:

在Search.Data项目中新建hbm目录,并在该目录下新建一个Dir.hbm.xml的XML文件如下:

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">

    <class name="Search.Data.Area, Search.Data" table="aArea">

          <id name="Id" column="id" unsaved-value="0">

               <generator class="identity" />

          </id>

          <property name="Name" type="String" column="Name" />

          <many-to-one name="UpArea" column="upId" />

          <property name="AreaType" column="AreaType" />

          <property name="UrlCount" column="UrlCount" />

          <property name="AreaPath" column="AreaPath" />

     </class>

</hibernate-mapping>

 注意粗体的这一句,其中“Search.Data.Area”为数据类的名称,“Search.Data”为该项目的装配集名称,“aArea”为数据库表名。

? 2、编写数据对象的类:

??? 在该项目中新建一个类代码文件“Search.Data.Area.cs”如下:

using System;

 

using NHibernate;

using Search.Data;

using Search.Core.Utils;

 

namespace Search.Core.Mid

{

     /// <summary>

     ///<b>[模块名称]</b>AreaImpl对区域的管理<br>

     ///<remarks>

     ///<b>[功能描述]</b> <br>

     ///           1)添加区域、修改、删除<br>

     ///           2<br>

     ///</remarks>

     ///<remarks>

     ///<b>[作者]</b>          <b><br>

     ///</remarks>

     ///<remarks>

     ///-------------------------------------------------------<br>

     ///<b>[修改历史]</b><br>

     ///2004-04-14    Initial creation       <br>

     ///-------------------------------------------------------<br>

     ///</remarks>

     /// </summary>

     public class AreaImpl

     {

         private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(AreaImpl));

 

         public AreaImpl()

         {

         }

 

    public void AddArea(Area area)

         {

              ISession s = HibernateUtil.OpenSession();

              ITransaction t = s.BeginTransaction();

              try

              {

                   s.Save(area);

                   t.Commit();

                   log.Info("Save " + area.ToString() + " ...OK");

              }

              catch(Exception e)

              {

                   t.Rollback();

                   log.Error("Save " + area.ToString() + " ...Failed!", e);

                   throw e;

              }

              finally

              {

                   s.Close();

              }

         }

 

         public void UpdateArea(Area area)

         {

              ISession s = HibernateUtil.OpenSession();

              ITransaction t = s.BeginTransaction();

              try

              {

                   s.Save(area);

                   t.Commit();

                   log.Info("Update " + area.ToString() + " ...OK");

              }

              catch(Exception e)

              {

                   t.Rollback();

                   log.Error("Update " + area.ToString() + " ...Failed!", e);

                   throw e;

              }

              finally

              {

                   s.Close();

              }

         }

 

         public void DeleteArea(int areaId)

         {

              Area area = (Area)Util.LoadObject(typeof(Area), areaId, false);

              if (area == null)

              {

                   throw new Exception("No object " + typeof(Area).ToString() + " ID:" + areaId);

              }

              this.DeleteArea(area);

         }

 

         public void DeleteArea(Area area)

         {

              ISession s = HibernateUtil.OpenSession();

              ITransaction t = s.BeginTransaction();

              try

              {

                   s.Delete(area);

                   t.Commit();

                   log.Info("Delete " + area.ToString() + " ...OK");

              }

              catch(Exception e)

              {

                   t.Rollback();

                   log.Error("Delete " + area.ToString() + " ...Failed!", e);

                   throw e;

              }

              finally

              {

                   s.Close();

              }

         }

     }

}

 

三、编写中间层应用:

??? 在Search.Core中编写以下类:

??? 1、新建一个NHibernateUtil持久Session工厂工具类HibernateUtil.cs,代码如下,注意该类中使用了SingleTon模式,确保Session工厂的唯一性:

using System;

using System.Reflection;

using System.Data;

using System.Data.SqlClient;

 

using NHibernate;

using NHibernate.Cfg;

using NHibernate.Dialect;

using NHibernate.Tool.hbm2ddl;

 

namespace Search.Core.Utils

{

     /// <summary>

     ///<b>[模块名称]</b>HibernateUtil NHibernateSession工厂工具<br>

     ///<remarks>

     ///<b>[功能描述]</b> <br>

     ///         采用SingleTon建立Session工厂;

     ///</remarks>

     ///<remarks>

     ///<b>[作者]</b>           <b><br>

     ///</remarks>

     ///<remarks>

     ///-----------------------------------------------------------<br>

     ///<b>[修改历史]</b><br>

     ///2004-04-15    Initial creation       <br>

     ///-------------------------------------------------------<br>

     ///</remarks>

     /// </summary>

     public class HibernateUtil

     {

         private static ISessionFactory sessions;

         private static Configuration cfg;

         private static Dialect dialect;

 

         private HibernateUtil()

         {

         }

 

         public static ISession OpenSession()

         {

              if (sessions == null)

              {

                   //创建Session工厂

                   BuildSessionFactory();

              }

              return sessions.OpenSession();

         }

        

         private static void BuildSessionFactory()

         {

              ExportSchema( new string[] {

                                                                                "Area.hbm.xml",

                                                                                "Dir.hbm.xml"

                                                                            } , false);

         }

 

         private static void ExportSchema(string[] files, bool exportSchema)

         {

              cfg = new Configuration();

 

              for (int i=0; i<files.Length; i++)

              {

                   cfg.AddResource("Search.Data.hbm." + files[i], Assembly.Load("Search.Data"));

              }

 

              dialect = Dialect.GetDialect();

 

              if(exportSchema) new SchemaExport(cfg).Create(true, true);

 

              sessions = cfg.BuildSessionFactory( );

         }

 

         /// <summary>

         /// Drops the schema that was built with the TestCase's Configuration.

         /// </summary>

         public void DropSchema()

         {

              new SchemaExport(cfg).Drop(true, true);

         }

     }

}

 

2、编写中间层应用类AreaImpl.cs,注意事务的控制,另该类中使用了Log4net作为日志工具。

using System;

using NHibernate;
using Search.Data;
using Search.Core.Utils;

namespace Search.Core.Mid
{
 /// <summary>
 ///<b>[模块名称]</b>AreaImpl对区域的管理<br>
 ///<remarks>
 ///<b>[功能描述]</b> <br>
 ///   1)添加区域、修改、删除<br>
 ///   2)<br>
 ///</remarks>
 ///<remarks>
 ///<b>[作者]</b>        <b><br>
 ///</remarks> 
 ///<remarks>
 ///-------------------------------------------------------<br>
 ///<b>[修改历史]</b><br>
 ///2004-04-14  Initial creation  <br>
 ///-------------------------------------------------------<br>
 ///</remarks>
 /// </summary>
 public class AreaImpl
 {
  private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(AreaImpl));

  public AreaImpl()
  {
  }

    public void AddArea(Area area)
  {
   ISession s = HibernateUtil.OpenSession();
   ITransaction t = s.BeginTransaction();
   try
   {
    s.Save(area);
    t.Commit();
    log.Info("Save " + area.ToString() + " ...OK");
   }
   catch(Exception e)
   {
    t.Rollback();
    log.Error("Save " + area.ToString() + " ...Failed!", e);
    throw e;
   }
   finally
   {
    s.Close();
   }
  }

  public void UpdateArea(Area area)
  {
   ISession s = HibernateUtil.OpenSession();
   ITransaction t = s.BeginTransaction();
   try
   {
    s.Save(area);
    t.Commit();
    log.Info("Update " + area.ToString() + " ...OK");
   }
   catch(Exception e)
   {
    t.Rollback();
    log.Error("Update " + area.ToString() + " ...Failed!", e);
    throw e;
   }
   finally
   {
    s.Close();
   }
  }

  public void DeleteArea(int areaId)
  {
   Area area = (Area)Util.LoadObject(typeof(Area), areaId, false);
   if (area == null)
   {
    throw new Exception("No object " + typeof(Area).ToString() + " ID:" + areaId);
   }
   this.DeleteArea(area);
  }

  public void DeleteArea(Area area)
  {
   ISession s = HibernateUtil.OpenSession();
   ITransaction t = s.BeginTransaction();
   try
   {
    s.Delete(area);
    t.Commit();
    log.Info("Delete " + area.ToString() + " ...OK");
   }
   catch(Exception e)
   {
    t.Rollback();
    log.Error("Delete " + area.ToString() + " ...Failed!", e);
    throw e;
   }
   finally
   {
    s.Close();
   }
  }
 }
}


三、编写表现层

??? 哈表现层就不用写了吧,直接调用AreaImpl类就可以了。。。还是说说吧

??? 1、增加Dir(注,这是另一个数据对象)

DirImpl ob = new DirImpl();

              Dir dir = new Dir();

              dir.Id = this.lbDirId.Text.Trim();

              dir.Name = this.lbDirName.Text.Trim();

              dir.UpDir = (Dir)Util.LoadObject(typeof(Dir), this.upId, false);

              dir.UrlCount = 0;

              ob.AddDir(dir);

??? 2、删除。。。

posted on Monday, April 26, 2004 8:07 PM