代码改变世界

nHibernate学习小结及代理模板

2008-07-11 15:00  莫耶  阅读(2466)  评论(8编辑  收藏  举报
  近日为学习Spring.net,开始上手nHibernate,其间遇到不少问题,但也小有收获,毕竟学习新框架是有曲线的

现小结一下,算是汇报:

1、关于配置文件
在web项目中,大部分的配置都是在web.config中进行部署,这样的好处是整合了各种应用的配置,维护比较集中。
由于使用的nHibernate为1.2.1GA,故而它对应的urn(统一资源名称,Uniform Resource Name, URN)为:“nhibernate-configuration-2.2”,这个常识性问题曾经困扰了我很久,运行时经常出现的异常诸如“not found section:'session-factory'”,其实是由于使用CodeSmith生成的模板文件(hbm.xml)中声明的urn为“nhibernate-configuration-2.0”所致。
在web.config中,进行这样的配置,是正确的:

  <configSections>
    
<section
            
name="hibernate-configuration"
            type
="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
  
</configSections>
  
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    
<session-factory xmlns="urn:nhibernate-configuration-2.2">
      
<property name="hibernate.connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
      
<property name="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
      
<property name="hibernate.connection.connection_string">Server=Locke.mo;database=woodigg;User Id=locke;Password=locke</property>
      
<property name="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</property>
      
<property name="show_sql">false</property>
      
<property name="use_proxy_validator">false</property>
      
<property name="use_outer_join">true</property>
    
</session-factory>
  
</hibernate-configuration>

2、使用Session的Load方法获取的对象只是个代理对象!
这意味着这个对象,你只能在Session的生命周期内使用它,一旦Session关闭,此对象也终止服务,如果此后试图访问它,将抛出“Exception initializing proxy”异常。
因为,在整个Session范围内,应用程序没有访问过这个代理类对象,那么代理类的实例一直不会被初始化,Hibernate不会执行任何select语句。(来自JavaEye)
我的解决办法是,强制其实例化:     
  //在Session范围内显式初始化代理类实例
  if (!NHibernateUtil.IsInitialized(t))
    NHibernateUtil.Initialize(t);

3、在《Spring in Action》一书中,作者提到Spring和其他数据持久化框架集成时,都提供了强大的模板类(如JdbcTemplate、HibernateTemplate等),真是令人羡慕的功能,毕竟大部分的DAO类里有着很多重复繁冗的代码,而这80%的代码其实是与具体业务无关的!
   既然现在还未到集成Spring.Net的地步,那就先为nHibernate单独实现一个模板吧:

using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using log4net;

namespace woodigg.DAO
{
    
/// <summary>
    
/// 增删改模板
    
/// </summary>

    public class HibernateTemplate
    
{
        
/// <summary>
        
/// 泛型读取
        
/// </summary>
        
/// <param name="obj"></param>
        
/// <param name="id"></param>

        public static T LoadFromId<T>(object id)
        
{
            ISession session 
= Sessions.GetSession();
            
try
            
{
                T t 
= session.Load<T>(id);
                
//在Session范围内显式初始化代理类实例
                if (!NHibernateUtil.IsInitialized(t))
                    NHibernateUtil.Initialize(t);
                
return t;
            }

            
catch (Exception ex)
            
{
                ILog log 
= LogManager.GetLogger(typeof(HibernateTemplate));
                log.Error(ex.Message, ex);
                
return default(T);
            }

            
finally
            
{
                session.Close();
            }

        }


        
/// <summary>
        
/// 存
        
/// </summary>
        
/// <param name="obj"></param>

        public static bool Save(object obj)
        
{
            ISession session 
= Sessions.GetSession();
            ITransaction trans 
= null;
            
try
            
{
                trans 
= session.BeginTransaction();
                session.Save(obj);
                trans.Commit();
                
return true;
            }

            
catch (Exception ex)
            
{
                ILog log 
= LogManager.GetLogger(typeof(HibernateTemplate));
                log.Error(ex.Message, ex);
                trans.Rollback();
                
return false;
            }

            
finally
            
{
                session.Close();
            }

        }


        
/// <summary>
        
/// 更新
        
/// </summary>
        
/// <param name="obj"></param>

        public static bool Update(object obj)
        
{
            ISession session 
= Sessions.GetSession();
            ITransaction trans 
= null;
            
try
            
{
                trans 
= session.BeginTransaction();
                session.Update(obj);
                trans.Commit();
                
return true;
            }

            
catch (Exception ex)
            
{
                ILog log 
= LogManager.GetLogger(typeof(HibernateTemplate));
                log.Error(ex.Message, ex);
                trans.Rollback();
                
return false;
            }

            
finally
            
{
                session.Close();
            }

        }


        
/// <summary>
        
/// 删
        
/// </summary>
        
/// <param name="obj"></param>

        public static bool Delete(object obj)
        
{
            ISession session 
= Sessions.GetSession();
            ITransaction trans 
= null;
            
try
            
{
                trans 
= session.BeginTransaction();
                session.Delete(obj);
                trans.Commit();
                
return true;
            }

            
catch (Exception ex)
            
{
                ILog log 
= LogManager.GetLogger(typeof(HibernateTemplate));
                log.Error(ex.Message, ex);
                trans.Rollback();
                
return false;
            }

            
finally
            
{
                session.Close();
            }

        }


        
/// <summary>
        
/// 查询
        
/// </summary>
        
/// <param name="obj"></param>

        public static IList<T> Seek<T>(string where)
        
{
            ISession session 
= Sessions.GetSession();
            
try
            
{
                
//模板反射
                T obj = (T)System.Reflection.Assembly.GetAssembly(typeof(T)).CreateInstance(typeof(T).ToString());

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

                IQuery query 
= session.CreateQuery(hql);

                IList
<T> list = query.List<T>();
                
return list;
            }

            
catch (Exception ex)
            
{
                ILog log 
= LogManager.GetLogger(typeof(HibernateTemplate));
                log.Error(ex.Message, ex);
                
return null;
            }

            
finally
            
{
                session.Close();
            }

        }

    }

}


差点忘了,它用到的SessionFactory:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using NHibernate;
using NHibernate.Cfg;

namespace woodigg.DAO
{
    
public class Sessions
    
{
        
private static readonly object lockObj = new object();          // 用于singleton模式进行锁定
        private static ISessionFactory _factory;                        // sesssion 工厂

        
public Sessions()
        
{
        }


        
/// <summary>
        
/// 单一静态工厂
        
/// </summary>

        public static ISessionFactory Factory
        
{
            
get {
                
if (_factory == null)
                
{
                    
lock (lockObj)          // 保证线程安全
                    {
                        
if (_factory == null)
                        
{
                            
// 查找hibernate.cfg.xml
                            Configuration cfg = new Configuration().Configure();
                            
// 不需要mapping,直接获取当前运行程序集
                            cfg.AddAssembly(Assembly.GetExecutingAssembly());
                            _factory 
= cfg.BuildSessionFactory();
                        }

                    }

                }

                
return _factory;
            }

        }


        
/// <summary>
        
/// 打开一个会话连接
        
/// </summary>
        
/// <returns></returns>

        public static ISession GetSession()
        
{
            
return Factory.OpenSession();
        }

    }

}
Creative Commons License
本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 Unported许可协议
欢迎转载,但必须保留文章的署名老莫的帐本子
并保留此链接:http://moye.cnblogs.com/
如有疑问请发邮件:moyerock@gmail.com