hibernate.initialize
持久化时,有时需要动态的改变对象的加载,比如在编辑页面里面lazy=true,而在浏览页面lazy=false,这样可以在需要lazy的地方才进行控制。而配置文件中lazy属性是全局控制的,如何处理呢?
当<class>元素或者<set>元素的lazy属性为true时,load() or get() or find()加载这些对象时,hibernate不会马上产生任何select语句,只是产生一个obj代理类实例,只有在session没有关闭的情况下运行obj.getxxx()时才会执行select语句从数据库加载对象,如果没有运行任何obj.getxxx()方法,而session已经关闭,obj已成游离状态,此时再运行obj.getxxx()方法,hibernate就会抛出"could not initialize proxy - the owning session was closeed"的异常,是说obj代理类实例无法被初始化。然而想在session关闭之前不调用obj.getxxx()方法而关闭session之后又要用,此时只要在session关闭之前调用hibernate.initialize(obj)或者hibernate.initialize(obj.getxxx())即可,net.sf.hibernate.hibernate类的initialize()静态方法用于在session范围内显示初始化代理类实例。
在配置文件里面可以用lazy=true,在程序里面可以用强制加载的方法hibernate.initialize(object proxy) 方法强制加载这样就相当于动态改变为lazy=false。
但在使用时需要注意的一点是:其中的proxy是持久对象的关联对象属性,比如a实体,你要把a的关联实体b也检出,则要写hibernate.initialize(a.b)。
hibernatetemplate还提供一种更加灵活的方式来操作数据库,通过这种方式可以完全使用hibernate的操作方式。
hibernatetemplate的灵活访问方式是通过如下两个方法完成:
(1)object execute(hibernatecallback action)
(2)list execute(hibernatecallback action)
这两个方法都需要一个hibernatecallback的实例,hibernatecallback实例可在任何有效的hibernate数据访问中使用。
程序开发者通过hibernatecallback,可以完全使用hibernate灵活的方式来访问数据库,解决spring封装hibernate后灵活性不足的缺陷。
hibernatecallback是一个接口,该接口只有一个方法doinhibernate(org.hibernate.session session),
该方法只有一个参数session。通常,程序中采用实现hibernatecallback的匿名内部类来获取hibernatecallback的实例,
方法doinhibernate的方法体就是spring执行的持久化操作。
做分页:
public list findbypage(final string hql,
final int offset, final int pagesize)
{
//通过一个hibernatecallback对象来执行查询
list list = gethibernatetemplate()
.executefind(new hibernatecallback()
{
//实现hibernatecallback接口必须实现的方法
public object doinhibernate(session session)
throws hibernateexception, sqlexception
{
//执行hibernate分页查询
list result = session.createquery(hql)
.setfirstresult(offset)
.setmaxresults(pagesize)
.list();
return result;
}
});
return list;
}
public list findbypage(final string hql , final object value ,
final int offset, final int pagesize)
{
//通过一个hibernatecallback对象来执行查询
list list = gethibernatetemplate()
.executefind(new hibernatecallback()
{
//实现hibernatecallback接口必须实现的方法
public object doinhibernate(session session)
throws hibernateexception, sqlexception
{
//执行hibernate分页查询
list result = session.createquery(hql)
//为hql语句传入参数
.setparameter(0, value)
.setfirstresult(offset)
.setmaxresults(pagesize)
.list();
return result;
}
});
return list;
}
public list findbypage(final string hql, final object[] values,
final int offset, final int pagesize)
{
//通过一个hibernatecallback对象来执行查询
list list = gethibernatetemplate()
.executefind(new hibernatecallback()
{
//实现hibernatecallback接口必须实现的方法
public object doinhibernate(session session)
throws hibernateexception, sqlexception
{
//执行hibernate分页查询
query query = session.createquery(hql);
//为hql语句传入参数
for (int i = 0 ; i < values.length ; i++)
{
query.setparameter( i, values[i]);
}
list result = query.setfirstresult(offset)
.setmaxresults(pagesize)
.list();
return result;
}
});
return list;
}
}