NHibernate性能的思考

“省事的活多半效率不高”,对编程来说,很多时候适用。NHibernate省却我们写Sql语句、存储过程,且数据库的移植又是相当方便,效率估计有一些影响。

那影响有多大呢?

为此我利用一个现有的WebService,试图去比较使用NHibernate和直接使用SqlClient之间的性能差异。

private ISessionFactory _sessions;
public void Configure()
{
    Configuration cfg 
= new Configuration();
    cfg.SetProperty(
"hibernate.connection.provider","NHibernate.Connection.DriverConnectionProvider");
    cfg.SetProperty(
"hibernate.dialect","NHibernate.Dialect.MsSql2000Dialect");
    cfg.SetProperty(
"hibernate.connection.driver_class","NHibernate.Driver.SqlClientDriver");
    cfg.SetProperty(
"hibernate.connection.connection_string","Server=localhost;initial catalog=Supercargo;user id=sa;password=network");

    cfg.AddClass(
typeof(Supercargo.Batch));
    cfg.AddClass(
typeof(Supercargo.Product));
    cfg.AddClass(
typeof(Supercargo.BatchItem));
    
this._sessions = cfg.BuildSessionFactory();
}


每一次的都从头到尾执行一次
this.Configure();
ISession session 
= _sessions.OpenSession();
ITransaction transaction 
= session.BeginTransaction();

session.Save(product1);
transaction.Commit();
session.Close();

SqlClient也一样从头到尾
SqlConnection connect = new SqlConnection("Server=localhost;initial"); 
try
{
    connect.Open();
    
    SqlCommand cmd 
= new SqlCommand(sql,connect);
    cmd.ExecuteNonQuery();
}

catch(Exception ee)
{
    str
= string.Format("语句:{0} \r\n错误:{1}",sql, ee.Message);
}

connect.Close();

执行100次的以上操作,NHibernate用了近6秒,直接使用SqlClient却用了不到2秒。NHibernate真的如此不济?

稍作思考,将NHibernate的过程分解了一下。首先使用一个类包装一下Configure
/// <summary>
/// DbConfigure 的摘要说明。
/// </summary>

public class DbConfigure
{
    
/// <summary>
    
/// 获取 Web应用程序的当前配置
    
/// </summary>

    public static DbConfigure CurrentConnect
    
{
        
get
        
{
            DbConfigure con 
= null;
            
object obj = System.Web.HttpContext.Current.Application["Connect"];
            
if(obj == null)
            
{
                con 
= new DbConfigure();                    
                System.Web.HttpContext.Current.Application[
"Connect"= con;
            }

            
else
                con 
= (DbConfigure)obj;

            
return con;
        }

    }


    
/// <summary>
    
/// 构造函数
    
/// </summary>

    public DbConfigure()
    
{                
        
this.configure();        
    }


    
/// <summary>
    
/// 打开连接。
    
/// </summary>
    
/// <returns></returns>

    public ConnectSession OpenSession()
    
{
        
return new ConnectSession(this._sessions.OpenSession());
    }
                        

    
private ISessionFactory _sessions;
    
private void configure()
    
{        
        Configuration cfg 
= new Configuration();
        cfg.SetProperty(
"hibernate.connection.provider","NHibernate.Connection.DriverConnectionProvider");
        cfg.SetProperty(
"hibernate.dialect","NHibernate.Dialect.MsSql2000Dialect");
        cfg.SetProperty(
"hibernate.connection.driver_class","NHibernate.Driver.SqlClientDriver");
        cfg.SetProperty(
"hibernate.connection.connection_string","Server=localhost;initial catalog=Superca");
        cfg.AddClass(
typeof(SD.Supercargo.Batch));
        cfg.AddClass(
typeof(SD.Supercargo.Product));
        cfg.AddClass(
typeof(SD.Supercargo.BatchItem));            
        
this._sessions = cfg.BuildSessionFactory();                
    }
        
}

也将ISession简单的封装到ConnectSession中
    /// <summary>
    
/// ConnectSession 的摘要说明。
    
/// </summary>

    public class ConnectSession
    
{
        
public ConnectSession(ISession pSession)
        
{            
            
this.mDbSession = pSession;
        }


        
public void Close()
        
{
            
this.mDbSession.Close();
        }


        
public void BeginTransaction()
        
{
            
this.mTransaction = this.mDbSession.BeginTransaction();
        }


        
public void CommitTransaction()
        
{
            
this.mTransaction.Commit();
        }


        
public void Update(object obj)
        
{
            
this.DbSession.Update(obj);
        }


        
public void Save(object obj)
        
{
            
this.DbSession.Save(obj);
        }


        
public void SaveOrUpdate(object obj)
        
{
            
this.DbSession.SaveOrUpdate(obj);
        }


        
private ITransaction mTransaction;
        
/// <summary>
        
/// 设置、获取Transaction
        
/// </summary>

        public ITransaction Transaction
        
{
            
get
            
{
                
if(this.mTransaction == null)
                    
this.mTransaction = this.mDbSession.BeginTransaction();
                
return this.mTransaction;
            }
            
        }

        
private ISession mDbSession;
        
/// <summary>
        
/// 获取DbSession
        
/// </summary>

        public ISession DbSession
        
{
            
get{return this.mDbSession;}            
            
set{this.mDbSession = value;}
        }

    }

测试过程只执行以下几步
DbConfigure con = DbConfigure.CurrentConnect;
ConnectSession connect 
= con.OpenSession();

ProductLocator prdLoc 
= new ProductLocator(connect.DbSession);
Product prd 
= new Product();
//一些赋值操作
connect.BeginTransaction();
prdLoc.Update(prd);
connect.CommitTransaction();
connect.Close();

NHibernate的成绩一下子提高到只需1.3秒多些,只稍慢于SqlClient的1.2秒,同样是操作100次。代码上的差异主要是用Application保存DbConfigure,Web应用程序只主要在启动的时候执行DbConfigure的Configure方法
public static DbConfigure CurrentConnect
{
    
get
    
{
        DbConfigure con 
= null;
        
object obj = System.Web.HttpContext.Current.Application["Connect"];
        
if(obj == null)
        
{
            con 
= new DbConfigure();                    
            System.Web.HttpContext.Current.Application[
"Connect"= con;
        }

        
else
            con 
= (DbConfigure)obj;

        
return con;
    }

}


当然对于windows应用程序就可以省下这个心了。看来NHibernate的是相当值得使用!
posted @ 2006-02-08 15:06  生命体验之kevin-Y  阅读(11999)  评论(8编辑  收藏