帐本子
二手代码贩子
posts - 18, comments - 52, trackbacks - 0, articles - 0
nHibernate学习小结及代理模板
Posted on 2008-07-11 15:00
莫耶
阅读(1480)
评论(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();
}
}
}
Tag标签:
Spring.net
,
nHibernate
,
o/r mapping
,
模板
,
Exception initializing proxy
Feedback
#1楼
回复
引用
查看
2008-07-11 15:02 by
Selfocus
好,学习学习!
#2楼
回复
引用
查看
2008-07-11 16:34 by
kiler
推荐使用SessionFactory的GetCurrentSession()来获取session,这样来说可以更方便的管理Session的生命周期,可以通过设置hibernate.current_session_context_class来定义如何管理Session的生命周期。
#3楼
回复
引用
查看
2008-07-11 18:30 by
wind.hong
楼主可以把背景音乐关了么?呵呵,感觉会比较安静,小小建议 :)
#4楼
回复
引用
查看
2008-07-11 20:52 by
Klesh Wong
实体类返回后session即被关闭,那,LazyLoad会用不了吧?
好像还是直接用ISession好吧。
#5楼
回复
引用
2008-07-12 13:37 by
adfadsfadfadfa [未注册用户]
d楼主可以把背景音乐关了么?呵呵,感觉会比较安静,小小建议 :)
#6楼
回复
引用
查看
2008-07-12 13:49 by
kanne
帮我关下背景音乐嘛?
#7楼
[
楼主
]
回复
引用
查看
2008-07-12 14:19 by
莫耶
应广大观众强烈要求
将扰人的背景音乐进行了关闭
期限是一万年
#8楼
[
楼主
]
回复
引用
查看
2008-07-12 14:22 by
莫耶
@kiler
对,你说的很有道理
正在进一步研究中
session的生命周期管理
才是应用nHibernate的关键