您的位置:首页 > 数据库

NHibernate 配置文件的处理和使用多数据库的多层架构思路(补充部分二)

2007-08-31 15:21 801 查看
第二种情况:多线程,比如.Net Remoting。
我现在就是遇见Net Remoting,才迫使我写这些东西的!每活动的个线程维护一个 session 。自然就提到了这个属性:System.ThreadStaticAttribute,MSDN是这样描述的:用 ThreadStaticAttribute 标记的 static 字段不在线程之间共享。每个执行线程都有单独的字段实例,并且独立地设置及获取该字段的值。如果在不同的线程中访问该字段,则该字段将包含不同的值。不要为标记为 ThreadStaticAttribute 的字段指定初始值,因为这样的初始化只会发生一次,因此在类构造函数执行时只会影响一个线程。在不指定初始值的情况下,如果它是值类型,可依赖初始化为其默认值的字段,如果它是引用类型,则可依赖初始化为空引用的字段。
那就不多说了,直接把(一)中底层的两个修改后的类 贴上来,它们是可以在多线程环境下运行的! CommonDatabaseOperation类没有任何变化!
EntityControl 类仅修改各个方法中的session 的重新连接和断开! 代码如下:


//-----------------------------------------------------------------------------------------


// 模块编号:


// 文件名: EntityControl.cs


// 描述: EntityControl 实体类


// 作者:ChenJie


// 编写日期:2007-5-11


// Copyright 2007


//-----------------------------------------------------------------------------------------


using System;


using System.Reflection;


using System.Collections;


using System.Collections.Generic;


using System.Text;


using System.Data;


using NHibernate;


using NHibernate.Cfg;


using NHibernate.Expression;


using NHibernate.Engine;


using NHibernate.SqlTypes;


using NHibernate.SqlCommand;




namespace Novelty.CustomSystem.NHibernateOperation.NHibernateModule






{




/**//// <summary>


/// 实体通用操作类


/// </summary>


public class EntityControl<T>






{




私有变量#region 私有变量


private ISession session;


#endregion






内部成员变量#region 内部成员变量


private string _assemblyName;


private string _nhibernateConfigName;


private string _connectionString;


#endregion






构造函数#region 构造函数




/**//// <summary>


/// 默认的构造函数


/// </summary>


public EntityControl()






{


}






/**//// <summary>


/// 构造函数


/// </summary>


/// <param name="assemblyName">程序集名称</param>


/// <param name="nhibernateConfigName">NHibernate 的配置文件名称</param>


/// <param name="connectionString">数据路字符串连接</param>


public EntityControl(string assemblyName, string nhibernateConfigName, string connectionString)






{


session = SessionFactory.Instance.OpenSession(assemblyName, nhibernateConfigName, connectionString);


_assemblyName = assemblyName;


_nhibernateConfigName = nhibernateConfigName;


_connectionString = connectionString;


}


#endregion






属性#region 属性




/**//// <summary>


/// 程序集名称


/// </summary>


public string AssemblyName






{


get






{


return _assemblyName;


}


set






{


if (_assemblyName == value)


return;


_assemblyName = value;


}


}






/**//// <summary>


/// NHibernate 的配置文件名称


/// </summary>


public string NhibernateConfigName






{


get






{


return _nhibernateConfigName;


}


set






{


if (_nhibernateConfigName == value)


return;


_nhibernateConfigName = value;


}


}






/**//// <summary>


/// 数据路字符串连接


/// </summary>


public string ConnectionString






{


get






{


return _connectionString;


}


set






{


if (_connectionString == value)


return;


_connectionString = value;


}


}


#endregion






方法#region 方法




/**//// <summary>


/// 增加实体对象


/// </summary>


/// <param name="entity">实体对象</param>


public void AddEntity(T entity)






{


if (!session.IsConnected)






{


session.Reconnect();


}


using (ITransaction transaction = session.BeginTransaction())






{


try






{


session.Save(entity);


transaction.Commit();


}


catch (Exception ex)






{


transaction.Rollback();


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


}


}






/**//// <summary>


/// 更新实体对象


/// </summary>


/// <param name="entity">实体对象</param>


/// <param name="key">关键字</param>


public void UpdateEntity(T entity, Object key)






{


if (!session.IsConnected)






{


session.Reconnect();


}


using (ITransaction transaction = session.BeginTransaction())






{


try






{


session.Update(entity, key);


transaction.Commit();


}


catch (Exception ex)






{


transaction.Rollback();


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


}


}






/**//// <summary>


/// 删除实体对象


/// </summary>


/// <param name="entity">实体对象</param>


public void DeleteEntity(T entity)






{


if (!session.IsConnected)






{


session.Reconnect();


}


using (ITransaction transaction = session.BeginTransaction())






{


try






{


session.Delete(entity);


transaction.Commit();


}


catch (Exception ex)






{


transaction.Rollback();


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


}


}






/**//// <summary>


/// 获得实体对象


/// </summary>


/// <param name="key">关键字</param>


/// <returns></returns>


public T GetEntity(Object key)






{


if (!session.IsConnected)






{


session.Reconnect();


}


T entity = default(T);


try






{


entity = session.Load<T>(key);


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return entity;


}








/**//// <summary>


/// 获得首行首列的值,类似执行 ExecuteScalar


/// 查询结果一般只有一条


/// 举例:hql = "SELECT MAX(systemLog.SystemLogId) FROM SystemLogInfo AS systemLog";


/// </summary>


/// <typeparam name="Y">类型</typeparam>


/// <param name="hql">NHibernate 查询语句</param>


/// <param name="defaultVale">默认值</param>


/// <returns></returns>


public Y GetDataFieldValue<Y>(string hql, Y defaultVale)






{


if (!session.IsConnected)






{


session.Reconnect();


}


Y dataFieldValue = defaultVale;


try






{


IQuery query = session.CreateQuery(hql);


IEnumerator<Y> itor = query.Enumerable<Y>().GetEnumerator();


itor.MoveNext();


try






{


dataFieldValue = itor.Current;


}




catch

{ }


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return dataFieldValue;


}






/**//// <summary>


/// 获得实体的数目


/// </summary>


/// <param name="entityName">实体名称</param>


/// <returns>实体的数目</returns>


public int GetCountOfEntities(string entityName)






{


if (!session.IsConnected)






{


session.Reconnect();


}


int count = 0;


StringBuilder sb = new StringBuilder();


sb.Append("SELECT COUNT(*) FROM ");


sb.Append(entityName);


try






{


IQuery query = session.CreateQuery(sb.ToString());


IEnumerator itor = query.Enumerable().GetEnumerator();


itor.MoveNext();


count = Convert.ToInt32(itor.Current);


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return count;


}






/**//// <summary>


/// 获得所有的实体对象列表


/// </summary>


/// <returns>对象列表</returns>


public IList<T> GetEntities()






{


if (!session.IsConnected)






{


session.Reconnect();


}


IList<T> entities = null;


try






{


entities = session.CreateCriteria(typeof(T)).List<T>();


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return entities;


}






/**//// <summary>


/// 通过条件获得实体对象列表


/// </summary>


/// <param name="propertyName">属性</param>


/// <param name="value">属性值</param>


/// <returns>对象列表</returns>


public IList<T> GetEntities(string propertyName, object value)






{


if (!session.IsConnected)






{


session.Reconnect();


}


IList<T> entities = null;


try






{


ICriteria criteria = session.CreateCriteria(typeof(T));


criteria.Add(Expression.Eq(propertyName, value));


entities = criteria.List<T>();


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return entities;


}






/**//// <summary>


/// 执行 SQL 语句并返回对象列表


/// 这个方法不能用,原因有二:


/// 一、这里NH的地盘,下面两个方法能完成这个功能。


/// 二、对于一对多的情况,反射的对象有问题,因为无法处理处理构造函数。


/// 这个方法放在这里是为了开阔一下思路。比如说,需要批量删除。当然,这个又涉及到参数的问题了!


/// 我不喜欢直接将参数拼到 sql 语句中,而是采用后来加载的方式!


/// </summary>


/// <param name="sql">SQL 语句</param>


/// <returns>查询的结果列表</returns>


[Obsolete("Do not call this method.")]


public IList<T> GetEntitiesByExecuteSQL(string sql)






{


if (!session.IsConnected)






{


session.Reconnect();


}


IList<T> entities = new List<T>();


Configuration cfg = SessionFactory.Instance.GetConfiguration(_assemblyName, _nhibernateConfigName, _connectionString);


try






{


using (ISessionFactoryImplementor s = (ISessionFactoryImplementor)cfg.BuildSessionFactory())






{


using (IDbConnection conn = s.OpenConnection())






{


IDbCommand cmd = conn.CreateCommand();


cmd.CommandType = CommandType.Text;


cmd.CommandText = sql;


using (IDataReader dr = cmd.ExecuteReader())






{


int fieldCount = 0;


object[] values = null;


while (dr.Read())






{


if (fieldCount == 0)






{


fieldCount = dr.FieldCount;


values = new Object[fieldCount];


}


for (int i = 0; i < fieldCount; i++)






{


values[i] = dr.GetValue(i);


}


Type t = typeof(T);


T obj = (T)Activator.CreateInstance(t, values);


entities.Add(obj);


}


}


}


}


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return entities;


}






/**//// <summary>


/// 执行 sql 语句查询获得实体对象列表


/// 举例:


/// sql = "SELECT * FROM SystemLog";


/// 注意:FROM 后是表的名称


/// /// </summary>


/// <param name="sql">sql 查询语句</param>


/// <returns>对象列表</returns>


public IList<T> GetEntitiesBySQL(string sql)






{


if (!session.IsConnected)






{


session.Reconnect();


}


IList<T> entities = null;


try






{


entities = session.CreateSQLQuery(sql).AddEntity(typeof(T)).List<T>();


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


finally






{


session.Disconnect();


}


return entities;


}






/**//// <summary>


/// 通过 NHibernate 查询语句获得实体对象列表


/// 举例:hql = "FROM SystemLogInfo WHERE UserSerial =1";


/// 注意:FROM 后是实体的名称


/// </summary>


/// <param name="hql">NHibernate 查询语句</param>


/// <returns></returns>


public IList<T> GetEntitiesByHQL(string hql)






{


if (!session.IsConnected)






{


session.Reconnect();


}


IList<T> entities = null;


try






{


entities = session.CreateQuery(hql).List<T>();


}


catch (Exception ex)






{


//记录日志, 抛出异常, 不包装异常


ExceptionFacade.LogAndThrowAndNoWrapPolicy(ex);


}


return entities;


}






/**//// <summary>


/// 将Ilist<T> 转换成 DataSet


/// </summary>


/// <param name="list"></param>


/// <returns></returns>


public DataSet ConvertToDataSet(IList<T> list)






{


if (list == null || list.Count <= 0)






{


return null;


}


DataSet ds = new DataSet();


DataTable dt = new DataTable(typeof(T).Name);


DataColumn column;


DataRow row;


PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);


foreach (T t in list)






{


if (t == null)






{


continue;


}


row = dt.NewRow();


for (int i = 0, j = myPropertyInfo.Length; i < j; i++)






{


PropertyInfo pi = myPropertyInfo[i];


string name = pi.Name;


if (dt.Columns[name] == null)






{


column = new DataColumn(name, pi.PropertyType);


dt.Columns.Add(column);


}


row[name] = pi.GetValue(t, null);


}


dt.Rows.Add(row);


}


ds.Tables.Add(dt);


return ds;


}




#endregion


}


}




SessionFactory 类改动较大,毕竟就是靠它的对象来为每个线程提供 session.




//-----------------------------------------------------------------------------------------


// 模块编号:


// 文件名: SessionFactory.cs


// 描述: SessionFactory 类


// 作者:ChenJie


// 编写日期:2007-5-11


// Copyright 2007


//-----------------------------------------------------------------------------------------


using System;


using System.Collections;


using System.Collections.Generic;


using System.Reflection;


using System.Data;


using NHibernate;


using NHibernate.Cfg;


using NHibernate.Tool.hbm2ddl;




namespace Novelty.CustomSystem.NHibernateOperation.NHibernateModule






{




/**//// <summary>


/// Session的创建类,属于单件模式(Singleton Pattern)


/// 一个数据库对应一个持久层项目,所以用对应的持久层项目的程序集名称来标识各自的ISessionFactory,Configuration,ISession各个类的对象


/// </summary>


public sealed class SessionFactory






{




私有变量#region 私有变量


//保存所有Sessions,一个数据库对应一个


private Dictionary<string, ISessionFactory> dicSessionFactorys = new Dictionary<string, ISessionFactory>(StringComparer.InvariantCultureIgnoreCase);


//保存所有Configurations, 一个数据库对应一个


private Dictionary<string, Configuration> dicConfigurations = new Dictionary<string, Configuration>(StringComparer.InvariantCultureIgnoreCase);


//保存所有Session


[ThreadStatic]


private Dictionary<string, ISession> dicSessions = null;


#endregion






构造函数#region 构造函数




/**//// <summary>


/// 构造函数


/// </summary>


SessionFactory()






{


}


#endregion






嵌套类#region 嵌套类


class Nested






{


static Nested()






{


}


internal static readonly SessionFactory instance = new SessionFactory();


}


#endregion






属性#region 属性




/**//// <summary>


/// 唯一实例


/// </summary>


public static SessionFactory Instance






{


get






{


return Nested.instance;


}


}


#endregion






实现公有方法#region 实现公有方法




/**//// <summary>


/// 通过 NHibernate 的配置文件(hibernate.cfg.xml)读取 NHibernate 配置信息。本例中采用的是将 NHibernate 的配置文件附加到该项目的程序集中。


/// 该配置文件中不包含程序集名称,通过 cfg.AddAssembly(assemblyName); 语句来添加。


/// 针对一个数据库就缓存了一个session, 本例中是通过程序集名称标识唯一的session。


/// </summary>


/// <param name="assemblyName">配置映射类的程序集名称</param>


/// <param name="nhibernateConfigName">NHibernate 的配置文件名称</param>


/// <param name="connectionString">数据路字符串连接</param>


/// <returns>ISession</returns>


public ISession OpenSession(string assemblyName, string nhibernateConfigName, string connectionString)






{


if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(nhibernateConfigName) || string.IsNullOrEmpty(connectionString))






{


return null;


}


ISession session = GetSessionByName(assemblyName);


if (session == null)






{


Configuration cfg = GetConfiguration(assemblyName, nhibernateConfigName, connectionString);


ISessionFactory sessionnFactory = GetSessionFactory(assemblyName, cfg);


session = sessionnFactory.OpenSession();


SaveSeesionByName(assemblyName, session);


}


return session;


}






/**//// <summary>


/// 获得 Configuration 对象


/// </summary>


/// <param name="assemblyName">配置映射类的程序集名称</param>


/// <param name="nhibernateConfigName">NHibernate 的配置文件名称</param>


/// <param name="connectionString">数据路字符串连接</param>


/// <returns>Configuration 对象</returns>


public Configuration GetConfiguration(string assemblyName, string nhibernateConfigName, string connectionString)






{


Configuration cfg = null;


//锁定 dicConfigurations 字典


lock (dicConfigurations)






{


if (!dicConfigurations.ContainsKey(assemblyName))






{


//复制到应用程序的 bin 目录下


//Configuration cfg = new Configuration().Configure();


//附加在程序集中


cfg = new Configuration().Configure(Assembly.GetExecutingAssembly(), nhibernateConfigName);


//添加程序集


//如果程序集很大,将导致速度很慢!解决方案如下:


//把该方法该为范型方法: public Configuration GetConfiguration<T>(string nhibernateConfigName, string connectionString)


//然后在写一个方法添加类: (1)首先cfg.AddClass(typeof(T)); (2)将与T相关的类一并添加进去!(一对一,一对多或是多对多的类之间都是有关系的)


cfg.AddAssembly(assemblyName);


Hashtable properties = new Hashtable();


properties.Add(NHibernate.Cfg.Environment.ConnectionString, connectionString);


cfg.AddProperties(properties);


dicConfigurations[assemblyName] = cfg;


}


else






{


cfg = dicConfigurations[assemblyName];


}


}


return cfg;


}


#endregion






实现私有方法#region 实现私有方法




/**//// <summary>


/// 通过程序集名获得一个 ISessionFactory 对象


/// </summary>


/// <param name="assemblyName"></param>


/// <param name="cfg"></param>


/// <returns></returns>


private ISessionFactory GetSessionFactory(string assemblyName, Configuration cfg)






{


ISessionFactory sessionnFactory = null;


lock (dicSessionFactorys)






{


if (!dicSessionFactorys.ContainsKey(assemblyName))






{


sessionnFactory = cfg.BuildSessionFactory();


dicSessionFactorys[assemblyName] = sessionnFactory;


}


else






{


sessionnFactory = dicSessionFactorys[assemblyName];


}


}


return sessionnFactory;


}






/**//// <summary>


/// 通过名称获得Session 保存Session


/// </summary>


/// <param name="name"></param>


/// <returns></returns>


private ISession GetSessionByName(string name)






{




/**////延迟初始化


if (dicSessions == null)






{


dicSessions = new Dictionary<string, ISession>(StringComparer.InvariantCultureIgnoreCase);


}


ISession session = null;


if (dicSessions.ContainsKey(name))






{


session = dicSessions[name];


if (session != null)






{


if (!session.IsConnected)






{


session.Reconnect();


}


}


}


return session;


}






/**//// <summary>


/// 通过名称保存Session


/// </summary>


/// <param name="name"></param>


/// <param name="value"></param>


private void SaveSeesionByName(string name, ISession value)






{


if (value.IsConnected)






{


value.Disconnect();


}


dicSessions[name] = value;


}


#endregion


}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐