在spring.net中集成nHibernate可以获得许多值得称道的特性。比如:基于元标记(meta Attributes)的事务支持、对物理数据库的抽象、对数据层进行切面式拦截。

  好处是不少,但首先要学会配置。为了这个集成的环境,建立一个配置文件 applicationContext.xml :
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <objects xmlns="http://www.springframework.net"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.net [url]http://www.springframework.net/xsd/spring-objects.xsd[/url]"
  5. >
  6.   <!--spring集合nHibernate-->
  7.   <object id="DbProvider" type="woodigg.DAO.SQLProvider,woodigg.DAO">
  8.     <property name="ConnectionString"
  9.           value="Server=(local);database=Music;User Id=sa;Password=******;Trusted_Connection=False" />
  10.   </object>

  11.   <!--session工厂-->
  12.   <object id="SessionFactory"
  13.           type="Spring.Data.NHibernate.LocalSessionFactoryObject, Spring.Data.NHibernate12">
  14.     <property name="DbProvider" ref="DbProvider" />
  15.     <property name="MappingAssemblies">
  16.       <list>
  17.         <value>woodigg.DAO</value>
  18.         <value>woodigg.model</value>
  19.       </list>
  20.     </property>
  21.     <property name="HibernateProperties">
  22.       <dictionary>
  23.         <entry key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
  24.         <entry key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" />
  25.         <entry key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
  26.         <entry key="show_sql" value="false" />
  27.         <entry key="hibernate.current_session_context_class" value="Spring.Data.NHibernate.SpringSessionContext, Spring.Data.NHibernate12"/>
  28.         <entry key="hibernate.query.factory_class" value="NHibernate.Hql.Classic.ClassicQueryTranslatorFactory" />
  29.         <entry key="hibernate.cache.provider_class" value="NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache" />
  30.         <entry key="relativeExpiration" value="5" />
  31.       </dictionary>
  32.     </property>
  33.   </object>
  34.   <!--事务管理器-->
  35.   <object id="HibernateTransactionManager"
  36.           type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate12">
  37.     <property name="DbProvider" ref="DbProvider" />
  38.     <property name="SessionFactory" ref="SessionFactory" />
  39.   </object>
  40.   <!--事务拦截器-->
  41.   <object id="TransactionInterceptor"
  42.           type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
  43.     <property name="TransactionManager" ref="HibernateTransactionManager" />
  44.     <property name="TransactionAttributeSource">
  45.       <object type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data" />
  46.     </property>
  47.   </object>
  48.   <!--HibernateTemplate-->
  49.   <object id="HibernateTemplate"
  50.           type="Spring.Data.NHibernate.HibernateTemplate,Spring.Data.NHibernate12">
  51.     <property name="SessionFactory" ref="SessionFactory" />
  52.   </object>
  53.   <!--Dao代理模板-->
  54.   <object id="DaoTemplate" type="woodigg.DAO.DaoTemplate, woodigg.DAO">
  55.     <property name="SessionFactory" ref="SessionFactory" />
  56.   </object>
  57.  
  58. </objects>
复制代码
OK,这里有几处需要说明:
  一、woodigg.DAO.SQLProvider 是一个数据结构类,用以描述物理数据库的相关信息,诸如连接串、元数据信息等。这里其实就用到了连接串,在配置中植入位置、帐号信息等就能连接到数据源。这个SQLProvider类结构如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Data;
  5. using Spring.Data.Common;

  6. namespace woodigg.DAO
  7. {
  8.     public class SQLProvider : IDbProvider
  9.     {
  10.         #region IDbProvider 成员
  11.         private string _connectionString = "";
  12.         public string ConnectionString
  13.         {
  14.             get
  15.             {
  16.                 return this._connectionString;
  17.             }
  18.             set
  19.             {
  20.                 this._connectionString = value;
  21.             }
  22.         }

  23.         public IDbCommand CreateCommand()
  24.         {
  25.             return null;
  26.         }

  27.         public object CreateCommandBuilder()
  28.         {
  29.             return null;
  30.         }

  31.         public IDbConnection CreateConnection()
  32.         {
  33.             return null;
  34.         }

  35.         public IDbDataAdapter CreateDataAdapter()
  36.         {
  37.             return null;
  38.         }

  39.         public IDbDataParameter CreateParameter()
  40.         {
  41.             return null;
  42.         }

  43.         public string CreateParameterName(string name)
  44.         {
  45.             return null;
  46.         }

  47.         public string CreateParameterNameForCollection(string name)
  48.         {
  49.             return null;
  50.         }

  51.         public IDbMetadata DbMetadata
  52.         {
  53.             get
  54.             {
  55.                 return null;
  56.             }
  57.         }

  58.         public string ExtractError(Exception e)
  59.         {
  60.             return null;
  61.         }

  62.         public bool IsDataAccessException(Exception e)
  63.         {
  64.             return false;
  65.         }

  66.         #endregion
  67.     }

  68. }
复制代码
二、在SessionFactory配置中,指明需要环境映射的程序集名称,通俗说法是:哪些层会在集成环境中,被直接引用?这里以示例项目来说是:woodigg.DAO和woodigg.Model,分别为实体(上一节中生成的一堆.cs实体)层,和数据映射文件(被嵌入在项目中的hbm.xml文件)所在的数据访问层。

  三、HibernateProperties节中,可以指定调试时是否显示生成的sql语句。同时,能配置缓存事宜:此处用到的是NHibernate.Caches.SysCache。

  四、配置HibernateTemplate。nHibernate的模板,既nHibernate项目已经为开发者写好了一套通用的方法,能便捷的操作数据库,此处将SessionFactory植入引用即能让它工作起来。(并不是所有的复杂SQL,它都能做到,不能完成的功能,我们得自己写,这个马上会交待)。

  五、DaoTemplate,就是我自己写的一个基于以上配置的复杂模板,能完成诸如Distinct,top,调用分页存储过程等一干复杂SQL功能,抛出来做点贡献吧:
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Data;
  6. using NHibernate;
  7. using NHibernate.Cfg;
  8. using NHibernate.Engine;
  9. using NHibernate.Expression;
  10. using Spring.Dao;
  11. using Spring.Data.NHibernate.Support;
  12. using woodigg.model;
  13. using log4net;

  14. namespace woodigg.DAO
  15. {
  16.     #region ParamInfo结构
  17.     public struct ParamInfo
  18.     {
  19.         public string Name;
  20.         public object Value;
  21.     }
  22.     #endregion

  23.     /// <summary>
  24.     /// 继续自HibernateDaoSupport抽象类
  25.     /// HibernateDaoSupport基类拥有HibernateTemplate
  26.     /// </summary>
  27.     public class DaoTemplate : HibernateDaoSupport
  28.     {       
  29.         /// <summary>
  30.         /// 泛型读取
  31.         /// </summary>
  32.         /// <param name="obj"></param>
  33.         /// <param name="id"></param>
  34.         #region T LoadFromId<T>(object id)
  35.         public T LoadFromId<T>(object id)
  36.         {
  37.             try
  38.             {               
  39.                 T obj =
  40.                     (T)HibernateTemplate.Load(typeof(T), id);
  41.                 return obj;
  42.             }
  43.             catch (Exception ex)
  44.             {
  45.                 ILog log = LogManager.GetLogger(typeof(T));
  46.                 log.Error(ex.Message, ex);
  47.                 return default(T);
  48.             }
  49.         }
  50.         #endregion

  51.         /// <summary>
  52.         /// 泛型存储
  53.         /// </summary>
  54.         /// <typeparam name="T"></typeparam>
  55.         /// <param name="obj"></param>
  56.         #region bool Save<T>(T obj)
  57.         public bool Save<T>(T obj)
  58.         {
  59.             try
  60.             {
  61.                 HibernateTemplate.Save(obj);
  62.                 return true;
  63.             }
  64.             catch (DataAccessException ex)
  65.             {
  66.                 ILog log = LogManager.GetLogger(typeof(T));
  67.                 log.Error(ex.Message, ex);
  68.                 return false;
  69.             }
  70.         }
  71.         #endregion

  72.         /// <summary>
  73.         /// 泛型更新
  74.         /// </summary>
  75.         /// <typeparam name="T"></typeparam>
  76.         /// <param name="obj"></param>
  77.         #region bool Update<T>(T obj)
  78.         public bool Update<T>(T obj)
  79.         {
  80.             try
  81.             {
  82.                 HibernateTemplate.Update(obj);
  83.                 return true;
  84.             }
  85.             catch (DataAccessException ex)
  86.             {
  87.                 ILog log = LogManager.GetLogger(typeof(T));
  88.                 log.Error(ex.Message, ex);
  89.                 return false;
  90.             }
  91.         }
  92.         #endregion

  93.         /// <summary>
  94.         /// 泛型删除
  95.         /// </summary>
  96.         /// <typeparam name="T"></typeparam>
  97.         /// <param name="obj"></param>
  98.         #region bool Delete<T>(T obj)
  99.         public bool Delete<T>(T obj)
  100.         {
  101.             try
  102.             {
  103.                 HibernateTemplate.Delete(obj);
  104.                 return true;
  105.             }
  106.             catch (DataAccessException ex)
  107.             {
  108.                 ILog log = LogManager.GetLogger(typeof(T));
  109.                 log.Error(ex.Message, ex);
  110.                 return false;
  111.             }
  112.         }
  113.         #endregion

  114.         /// <summary>
  115.         /// 条件删除
  116.         /// </summary>
  117.         /// <typeparam name="T"></typeparam>
  118.         /// <param name="where"></param>
  119.         #region bool Delete<T>(string where)
  120.         public bool Delete<T>(string where)
  121.         {
  122.             try
  123.             {
  124.                 string sql =string.Format("from {0} {1}",
  125.                     typeof(T).ToString(),
  126.                     where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where);
  127.                 HibernateTemplate.Delete(sql);
  128.                 return true;
  129.             }
  130.             catch (DataAccessException ex)
  131.             {
  132.                 ILog log = LogManager.GetLogger(typeof(T));
  133.                 log.Error(ex.Message, ex);
  134.                 return false;
  135.             }
  136.         }
  137.         #endregion

  138.         /// <summary>
  139.         /// 泛型搜索
  140.         /// </summary>
  141.         /// <typeparam name="T"></typeparam>
  142.         /// <param name="where"></param>
  143.         #region IList<T> Search<T>(string where)
  144.         public IList<T> Search<T>(string where)
  145.         {
  146.             try
  147.             {
  148.                 //有意思的模板反射哟~
  149.                 T obj = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());

  150.                 string hql = string.Format("from {0} {1}",
  151.                     obj.GetType().ToString(),
  152.                     where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where);

  153.                 IList alist =  HibernateTemplate.Find(hql);

  154.                 IList<T> list = new List<T>();
  155.                 if (alist != null && alist.Count > 0)
  156.                 {
  157.                     foreach (T t in alist)
  158.                     { list.Add(t); }
  159.                     return list;
  160.                 }
  161.                 else
  162.                     return null;
  163.                
  164.             }
  165.             catch (Exception ex)
  166.             {
  167.                 ILog log = LogManager.GetLogger(typeof(T));
  168.                 log.Error(ex.Message, ex);
  169.                 return null;
  170.             }
  171.         }
  172.         #endregion

  173.         /// <summary>
  174.         /// 泛型搜索 - DISTINCT
  175.         /// </summary>
  176.         /// <typeparam name="T"></typeparam>
  177.         /// <param name="field">列名,用","分开,不带别名</param>
  178.         /// <param name="where"></param>
  179.         /// <param name="alias">别名</param>
  180.         #region IList<T> SearchDistinct<T>(string where,string field,string alias)
  181.         public IList<T> SearchDistinct<T>(string where, string field, string alias)
  182.         {
  183.             try
  184.             {
  185.                 //有意思的模板反射哟~
  186.                 T obj = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());
  187.                 // 反射DTO对象的各字段,必须把字段和DB中字段同名
  188.                 System.Reflection.PropertyInfo[] pps = obj.GetType().GetProperties();

  189.                 //拆分成别名+列名
  190.                 string[] cols = field.Split(',');
  191.                 string columns = string.Empty;
  192.                 foreach (string col in cols)
  193.                     columns += string.Format("{0}.{1},", alias, col);
  194.                 columns = columns.TrimEnd(',');

  195.                 //hql
  196.                 string hql = string.Format("select distinct {2} from {0} {3} {1}",
  197.                     obj.GetType().ToString(),
  198.                     where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where
  199.                     , columns
  200.                     , alias);

  201.                 IList alist = HibernateTemplate.Find(hql);

  202.                 IList<T> list = new List<T>();
  203.                 if (alist != null && alist.Count > 0)
  204.                 {
  205.                     //是否为数组
  206.                     bool isArray = (cols.Length == 1 ? false : true);

  207.                     foreach (object arr in alist)
  208.                     {
  209.                         //产生一个类实例
  210.                         T t = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());


  211.                         for (int i = 0; i < cols.Length; i++)
  212.                         {
  213.                             //逐字段检查名称
  214.                             foreach (System.Reflection.PropertyInfo pi in pps)
  215.                             {
  216.                                 if(pi.Name.Equals(cols))
  217.                                 {
  218.                                     //数组与object对象
  219.                                     pi.SetValue(t, (isArray ? (arr as object[]) : arr), null);
  220.                                 }
  221.                             }
  222.                         }                     

  223.                         list.Add(t);
  224.                     }

  225.                     return list;
  226.                 }
  227.                 else
  228.                     return null;

  229.             }
  230.             catch (Exception ex)
  231.             {
  232.                 ILog log = LogManager.GetLogger(typeof(T));
  233.                 log.Error(ex.Message, ex);
  234.                 return null;
  235.             }
  236.         }
  237.         #endregion

  238.         /// <summary>
  239.         /// 基于表达式的排序查询
  240.         /// </summary>
  241.         /// <typeparam name="T"></typeparam>
  242.         /// <param name="where"></param>
  243.         /// <param name="propertyName"></param>
  244.         /// <param name="ascending"></param>
  245.         #region IList<T> SearchWithOrder<T>(string where, string propertyName, bool ascending)
  246.         public IList<T> SearchWithOrder<T>(string where, string propertyName, bool ascending)
  247.         {
  248.             try
  249.             {
  250.                 //排序
  251.                 Order order = new Order(propertyName, ascending);
  252.                 //排序
  253.                 ICriteria ic = Session.CreateCriteria(typeof(T));
  254.                 ic.AddOrder(order);
  255.                 //表达式
  256.                 ICriterion exp = Expression.Sql(where);
  257.                 ic.Add(exp);

  258.                 return ic.List<T>();
  259.             }
  260.             catch (Exception ex)
  261.             {
  262.                 ILog log = LogManager.GetLogger(typeof(T));
  263.                 log.Error(ex.Message, ex);
  264.                 return null;
  265.             }
  266.         }
  267.         #endregion

  268.         /// <summary>
  269.         /// 执行存储过程(返回bool)
  270.         /// </summary>
  271.         /// <param name="spName">名称</param>
  272.         /// <param name="paramInfos">参数表</param>
  273.         #region bool ExecuteStoredProc2(string spName, ICollection paramInfos)
  274.         public bool ExecuteStoredProc2(string spName, ICollection paramInfos)
  275.         {
  276.             bool result = true;

  277.             IDbCommand cmd = Session.Connection.CreateCommand();

  278.             cmd.CommandText = spName;
  279.             cmd.CommandType = CommandType.StoredProcedure;

  280.             // 加入参数
  281.             if (paramInfos != null)
  282.             {
  283.                 foreach (ParamInfo info in paramInfos)
  284.                 {
  285.                     IDbDataParameter parameter = cmd.CreateParameter();
  286.                     parameter.ParameterName = info.Name; // driver.FormatNameForSql( info.Name );
  287.                     parameter.Value = info.Value;
  288.                     cmd.Parameters.Add(parameter);
  289.                 }
  290.             }

  291.             IDbConnection conn = Session.Connection;
  292.             if(conn.State == ConnectionState.Closed)
  293.                 conn.Open();
  294.             try
  295.             {
  296.                 cmd.Connection = conn;
  297.                 IDataReader rs = cmd.ExecuteReader();
  298.                 result = true;
  299.             }
  300.             catch (Exception ex)
  301.             {
  302.                 ILog log = LogManager.GetLogger(typeof(DaoTemplate));
  303.                 log.Error(ex.Message, ex);
  304.                 result = false;
  305.             }
  306.             finally
  307.             {
  308.                 Session.Connection.Close();
  309.             }

  310.             return result;
  311.         }
  312.         #endregion

  313.         /// <summary>
  314.         /// 执行存储过程(返回ILIST)
  315.         /// </summary>
  316.         /// <param name="spName">名称</param>
  317.         /// <param name="paramInfos">参数表</param>
  318.         #region IList ExecuteStoredProc(string spName, ICollection paramInfos)
  319.         public IList ExecuteStoredProc(string spName, ICollection paramInfos)
  320.         {
  321.             IList result = new ArrayList();

  322.             IDbCommand cmd = Session.Connection.CreateCommand();               

  323.             cmd.CommandText = spName;
  324.             cmd.CommandType = CommandType.StoredProcedure;           

  325.             // 加入参数
  326.             if (paramInfos != null)
  327.             {
  328.                 foreach (ParamInfo info in paramInfos)
  329.                 {
  330.                     IDbDataParameter parameter = cmd.CreateParameter();
  331.                     parameter.ParameterName = info.Name; // driver.FormatNameForSql( info.Name );
  332.                     parameter.Value = info.Value;
  333.                     cmd.Parameters.Add(parameter);
  334.                 }
  335.             }

  336.             IDbConnection conn = Session.Connection;
  337.             conn.Open();
  338.             try
  339.             {
  340.                 cmd.Connection = conn;
  341.                 IDataReader rs = cmd.ExecuteReader();

  342.                 while (rs.Read())
  343.                 {
  344.                     int fieldCount = rs.FieldCount;
  345.                     object[] values = new Object[fieldCount];
  346.                     for (int i = 0; i < fieldCount; i++)
  347.                         values = rs.GetValue(i);
  348.                     result.Add(values);
  349.                 }
  350.             }
  351.             finally
  352.             {
  353.                 Session.Connection.Close();
  354.             }

  355.             return result;
  356.         }
  357.         #endregion

  358.         /// <summary>
  359.         /// 获取记录数
  360.         /// </summary>
  361.         /// <typeparam name="T"></typeparam>
  362.         /// <returns></returns>
  363.         #region  int GetRecordCount<T>(string where)
  364.         public int GetRecordCount<T>(string where)
  365.         {
  366.             return GetRecordCount<T>(where, "*");
  367.         }
  368.         #endregion

  369.         /// <summary>
  370.         /// 获取记录数
  371.         /// </summary>
  372.         /// <typeparam name="T"></typeparam>
  373.         /// <returns></returns>
  374.         #region  int GetRecordCount<T>(string where,string cols)
  375.         public int GetRecordCount<T>(string where,string cols)
  376.         {
  377.             try
  378.             {
  379.                 //DISTINCT统计
  380.                 bool distinct = false;
  381.                 if (cols.ToLower().StartsWith("distinct"))
  382.                 {
  383.                     distinct = true;
  384.                     string[] columns = cols.Replace("distinct", "").Split(',');
  385.                     StringBuilder sb = new StringBuilder();
  386.                     sb.Append("distinct ");
  387.                     for (int i = 0; i < columns.Length; i++)
  388.                         sb.Append("alia." + columns.Trim());
  389.                     cols = sb.ToString().TrimEnd(',');
  390.                 }

  391.                 T obj = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());
  392.                 string hql = "";
  393.                 if (where.Trim() == String.Empty)
  394.                 {
  395.                     hql = string.Format("select count({1}) from {0} {2}",
  396.                         obj.GetType().ToString(),cols
  397.                         ,(distinct ? "alia":"")
  398.                         );
  399.                 }
  400.                 else
  401.                 {
  402.                     hql = string.Format("select count({2}) from {0} {3} {1}",
  403.                         obj.GetType().ToString(),
  404.                         where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where
  405.                         , cols, (distinct ? "alia" : ""));
  406.                 }

  407.                 IQuery query = Session.CreateQuery(hql);               
  408.                 object o = query.UniqueResult();
  409.                 return int.Parse(o.ToString());
  410.             }
  411.             catch (Exception ex)
  412.             {
  413.                 ILog log = LogManager.GetLogger(typeof(T));
  414.                 log.Error(ex.Message, ex);
  415.                 return 0;
  416.             }
  417.             finally
  418.             {
  419.                 Session.Close();
  420.             }
  421.         }
  422.         #endregion

  423.         /// <summary>
  424.         /// 获取记录数(全文检索)
  425.         /// </summary>
  426.         /// <typeparam name="T"></typeparam>
  427.         /// <returns></returns>
  428.         #region int GetRecordCount4Fulltext<T>(string where,string tbName)
  429.         public int GetRecordCount4Fulltext<T>(string where, string tbName)
  430.         {
  431.             try
  432.             {
  433.                 string hql = string.Format("select count(*) as CountNum from {0} {1}",
  434.                         tbName,
  435.                         where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where);

  436.                 IQuery query = Session.CreateSQLQuery(hql)
  437.                     .AddScalar("CountNum", NHibernateUtil.Int32);
  438.                 object o = query.UniqueResult();
  439.                 return int.Parse(o.ToString());
  440.             }
  441.             catch (Exception ex)
  442.             {
  443.                 ILog log = LogManager.GetLogger(typeof(T));
  444.                 log.Error(ex.Message, ex);
  445.                 return 0;
  446.             }
  447.             finally
  448.             {
  449.                 Session.Close();
  450.             }
  451.         }
  452.         #endregion

  453.         /// <summary>
  454.         ///  通过where条件查询获取分页数据
  455.         /// </summary>
  456.         /// <typeparam name="T"></typeparam>
  457.         /// <param name="where"></param>
  458.         /// <param name="varQuerysort">排序</param>
  459.         /// <param name="Start"></param>
  460.         /// <param name="Max"></param>
  461.         /// <returns></returns>
  462.         #region  IList<T> GetPageEntites<T>(string where,string varQuerysort, int Start, int Max)
  463.         public IList<T> GetPageEntites<T>(string where, string varQuerysort, int Start, int Max)
  464.         {
  465.             try
  466.             {
  467.                 T obj = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());
  468.                 string hql = "";
  469.                 if (where.Trim() == String.Empty)
  470.                 {
  471.                     hql = string.Format("from {0}",
  472.                         obj.GetType().ToString());
  473.                 }
  474.                 else
  475.                 {
  476.                     hql = string.Format("from {0} {1}",
  477.                         obj.GetType().ToString(),
  478.                         where.ToUpper().StartsWith("WHERE") ? where : "WHERE " + where);
  479.                 }

  480.                 if (varQuerysort != String.Empty) hql += " " + varQuerysort;

  481.                 IQuery query = Session.CreateQuery(hql);

  482.                 IList<T> list = query.SetFirstResult(Start).SetMaxResults(Max).List<T>();

  483.                 return list;
  484.             }
  485.             catch (Exception ex)
  486.             {
  487.                 ILog log = LogManager.GetLogger(typeof(T));
  488.                 log.Error(ex.Message, ex);
  489.                 return null;
  490.             }
  491.             finally
  492.             {
  493.                 Session.Close();
  494.             }

  495.         }
  496.         #endregion

  497.         /// <summary>
  498.         /// 通过存储过程查询分页信息
  499.         /// </summary>
  500.         /// <param name="tableName">表名</param>
  501.         /// <param name="Primarykeyname"></param>
  502.         /// <param name="colName">列名集合</param>
  503.         /// <param name="orderCol">排序列名</param>
  504.         /// <param name="pageSize">页尺寸</param>
  505.         /// <param name="pageIdx">当前页</param>
  506.         /// <param name="orderType">升降序,true-0为升序,false-非0为降序</param>
  507.         /// <param name="condition">条件</param>
  508.         /// <returns></returns>
  509.         #region  public DataTable GetPageEntitesByStoredProc(string tableName, string Primarykeyname, string colName, string orderCol,int pageSize, int pageIdx, bool orderType, string condition)
  510.         public DataTable GetPageEntitesByStoredProc(string tableName, string Primarykeyname, string colName, string orderCol,
  511.             int pageSize, int pageIdx, bool orderType, string condition)
  512.         {
  513.             IList result = new ArrayList();

  514.             ISessionFactoryImplementor imp = (ISessionFactoryImplementor)SessionFactory;
  515.             IDbConnection conn = imp.ConnectionProvider.GetConnection();
  516.             IDbCommand cmd = imp.ConnectionProvider.GetConnection().CreateCommand();

  517.             cmd.CommandText = "pagination";
  518.             cmd.CommandType = CommandType.StoredProcedure;

  519.             IDbDataParameter parameter = cmd.CreateParameter();
  520.             parameter.ParameterName = "@tblName";
  521.             parameter.Value = tableName;
  522.             cmd.Parameters.Add(parameter);

  523.             parameter = cmd.CreateParameter();
  524.             parameter.ParameterName = "@PrimaryKey";
  525.             parameter.Value = Primarykeyname;
  526.             cmd.Parameters.Add(parameter);

  527.             parameter = cmd.CreateParameter();
  528.             parameter.ParameterName = "@strGetFields";
  529.             parameter.Value = colName;
  530.             cmd.Parameters.Add(parameter);

  531.             parameter = cmd.CreateParameter();
  532.             parameter.ParameterName = "@fldName";
  533.             parameter.Value = orderCol;
  534.             cmd.Parameters.Add(parameter);

  535.             parameter = cmd.CreateParameter();
  536.             parameter.ParameterName = "@PageSize";
  537.             parameter.Value = pageSize;
  538.             cmd.Parameters.Add(parameter);

  539.             parameter = cmd.CreateParameter();
  540.             parameter.ParameterName = "@PageIndex";
  541.             parameter.Value = pageIdx;
  542.             cmd.Parameters.Add(parameter);

  543.             parameter = cmd.CreateParameter();
  544.             parameter.ParameterName = "@OrderType";
  545.             parameter.Value = orderType;
  546.             cmd.Parameters.Add(parameter);

  547.             parameter = cmd.CreateParameter();
  548.             parameter.ParameterName = "@strWhere";
  549.             parameter.Value = condition;
  550.             cmd.Parameters.Add(parameter);

  551.             try
  552.             {
  553.                 cmd.Connection = conn;
  554.                 IDataReader rs = cmd.ExecuteReader();
  555.                 // 分割列
  556.                 string[] cols = SplitsColumnNames(colName, ',');
  557.                 // 数据表
  558.                 DataTable dt = new DataTable(tableName);
  559.                 foreach (string col in cols)
  560.                     dt.Columns.Add(col);

  561.                 // 取数据

  562.                 while (rs.Read())
  563.                 {
  564.                     // 创建行
  565.                     DataRow row = dt.NewRow();
  566.                     for (int i = 0; i < cols.Length; i++)
  567.                         row[cols] = rs.GetValue(i);
  568.                     // 插入行
  569.                     dt.Rows.Add(row);
  570.                 }
  571.                 // 返回结果集
  572.                 return dt;
  573.             }
  574.             catch (Exception ex)
  575.             {
  576.                 ILog log = LogManager.GetLogger(typeof(DaoTemplate));
  577.                 log.Error(ex.Message, ex);
  578.                 return null;
  579.             }
  580.             finally
  581.             {
  582.                 imp.CloseConnection(conn);
  583.             }
  584.         }
  585.         #endregion

  586.         /// <summary>
  587.         /// 将字符里的列表分解出来
  588.         /// </summary>
  589.         /// <returns></returns>
  590.         #region  internal static string[] SplitsColumnNames(string columns, char separator)
  591.         internal static string[] SplitsColumnNames(string columns, char separator)
  592.         {
  593.             return columns.Split(new char[] { separator });
  594.         }
  595.         #endregion
  596.     }
  597. }
复制代码
这是内个配合使用的sql server分页存储过程,原来从网上摘的,动手改过两次以适配distinct取数据:
  1. -- 获取指定页的数据
  2. CREATE PROCEDURE pagination
  3. @tblName varchar(255), -- 表名
  4. @PrimaryKey varchar(100), --主键
  5. @strGetFields varchar(1000) = '*', -- 需要返回的列
  6. @fldName varchar(255)='', -- 排序的字段名
  7. @PageSize int = 10, -- 页尺寸
  8. @PageIndex int = 1, -- 页码
  9. @doCount bit = 0, -- 返回记录总数, 非 0 值则返回
  10. @OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
  11. @strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
  12. AS
  13. declare @strSQL varchar(5000) -- 主语句
  14. declare @strTmp varchar(110) -- 临时变量
  15. declare @strOrder varchar(400) -- 排序类型
  16. if @doCount != 0
  17. begin
  18. if @strWhere !=''
  19. set @strSQL = "select count(*) as Total from " + @tblName + " where "+@strWhere
  20. else
  21. set @strSQL = "select count(*) as Total from " + @tblName + ""
  22. end
  23. --以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况
  24. else
  25. begin
  26. if @OrderType != 0
  27. begin
  28. --set @strTmp = "<(select min"
  29. set @strTmp = " not in "
  30. set @strOrder = " order by [" + @fldName +"] desc"
  31. --如果@OrderType不是0,就执行降序,这句很重要!
  32. end
  33. else
  34. begin
  35. --set @strTmp = ">(select max"
  36. set @strTmp = " not in "
  37. set @strOrder = " order by [" + @fldName +"] asc"
  38. end
  39. if @PageIndex = 1
  40. begin
  41. if @strWhere != ''
  42. set @strSQL = "select top " + str(@PageSize,3) +" "+@strGetFields+ " from " + @tblName + " where " + @strWhere + @strOrder
  43. else
  44. set @strSQL = "select top " + str(@PageSize,3) +" "+@strGetFields+ " from "+ @tblName + " "+ @strOrder
  45. --如果是第一页就执行以上代码,这样会加快执行速度
  46. end
  47. else
  48. begin
  49. --以下代码赋予了@strSQL以真正执行的SQL代码
  50. set @strSQL = "select top " + str(@PageSize,3) +" "+@strGetFields+ " from "
  51. + @tblName + " where [" + @PrimaryKey + "]" + @strTmp + "  (select top " + str((@PageIndex-1)*@PageSize,3) + " ["+ @PrimaryKey + "] from " + @tblName + "" + @strOrder + ") "+ @strOrder
  52. if @strWhere != ''
  53. set @strSQL = "select top " + str(@PageSize,3) +" "+@strGetFields+ " from "
  54. + @tblName + " where [" + @PrimaryKey + "]" + @strTmp
  55. + "  (select top " + str((@PageIndex-1)*@PageSize,3) + " ["
  56. + @PrimaryKey + "] from " + @tblName + " where " + @strWhere + " "
  57. + @strOrder + ")  and " + @strWhere + " " + @strOrder
  58. end
  59. end
  60. print @strSQL
  61. exec (@strSQL)
  62. GO
复制代码
最后,要让这个环境在程序中生效,得在web.config中加载它:
  1.     <configSections>
  2.         <sectionGroup name="spring">
  3.             <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
  4.             <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
  5.         </sectionGroup>
  6.         <section name="SpringOverrideProperty" type="System.Configuration.NameValueSectionHandler"/>
  7.         <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
  8.         <!--log4net-->
  9.         <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  10.     </configSections>   
  11.     <spring>
  12.         <context>
  13.             <resource uri="config://spring/objects"/>
  14.             <resource uri="~/config/applicationContext.xml"/>
  15.             <resource uri="~/config/business.xml"/>
  16.             <resource uri="~/config/controllers.xml"/>
  17.             <resource uri="~/config/pageConfig.xml"/>
  18.             <resource uri="~/config/serviceConfig.xml"/>
  19.         </context>
  20.         <objects xmlns="http://www.springframework.net"/>
  21.     </spring>
复制代码
先写到这里吧,博客园的编辑器对机器配置要求不低,粘贴几段代码,界面几乎不能动弹,做罢了。下一回,将介绍怎么应用这个集成的环境。 (文/莫耶

上一篇:.net企业级架构实战之3——业务对象建模及codesmith模板

下一篇:.net企业级架构实战之5——基于接口的访问层实现

--------------------------------------------------------------------------------
  这里放出一个项目的mini demo:精简版spring.net集成Demo,点击下载:
TOP