小马的天空
我为软狂

导航

 
“省事的活多半效率不高”,对编程来说,很多时候适用。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 on 2006-07-18 15:12  Vinson  阅读(262)  评论(0)    收藏  举报